一、简介
将master数据库中的DDL和DML操作通过二进制日志(BINLOG)传输到slave数据库上,然后将这些日志重新执行(重做);从而使得slave数据库的数据与master数据库保持一致。
MySQL数据库自身提供的主从复制功能可以方便的实现数据的多处自动备份,实现数据库的拓展。多个数据备份不仅可以加强数据的安全性,通过实现读写分离还能进一步提升数据库的负载性能。
二、主从同步原理
Binary log:主数据库的二进制日志
Relay log:从服务器的中继日志
2.1 主从复制基本原理:
从库生成两个线程,一个I/O线程,一个SQL线程;i/o线程去请求主库 的binlog,并将得到的binlog日志写到relay log(中继日志) 文件中;主库会生成一个 log dump 线程,用来给从库 i/o线程传binlog;SQL 线程,会读取relaylog文件中的日志,并解析成具体操作,来实现主从的操作一致,而终数据一致;
2.2 主从复制原理运行流程:
master在每个事务更新数据完成之前,将该操作记录串行地写入到binlog文件中;
slave开启一个I/O Thread,该线程在master打开一个普通连接,主要工作是binlog dump process。如果读取的进度已经跟上了master,就进入睡眠状态并等待master产生新的事件。I/O线程终的目的是将这些事件写入到中继日志中;
SQL Thread会读取中继日志,并顺序执行该日志中的SQL事件,从而与主数据库中的数据保持一致;
三、主从的形式和用途
3.1主从的形式
一主一从
主主复制
一主多从
多主一从
联及复制
联级复制就是master服务器,只给一台slave服务器同步数据,然后slave服务器在向后端的所有slave服务器同步数据,降低master服务器的写压力,和复制数据的网络IO。
3.2、主从用途
Ø 实时灾备,用于故障切换,主数据库出现问题,可以切换到从数据库
Ø 读写分离,提供查询服务
Ø 数据备份,避免影响业务
四、主从同步配置
4.1、前提
做主从同步做好两台数据库的版本一致。
4.2、查看两台数据库版本
使用mysql -V命令查看版本
4.3、修改主数据库配置文件
4.3.1、添加mysql-binlog存放路径并设置权限
[root@TCmysqlone mysql]# mkdir mysqld-binlog
[root@TCmysqlone mysql]# chown mysql:mysql mysqld-binlog/
4.3.2、修改主数据库主配置文件
注:主要修改的是配置文件中的mysqld项
[root@TCmysqlone my.cnf.d]# pwd
/etc/my.cnf.d
[root@TCmysqlone my.cnf.d]# cat server.cnf
#
# These groups are read by MariaDB server.
# Use it for options that only the server (but not clients) should see
#
# See the examples of server my.cnf files in /usr/share/mysql/
#
# this is read by the standalone daemon and embedded servers
[server]
# this is only for the mysqld standalone daemon
[mysqld]
#设置主从 的ID
server-id=1
#配置binlog的存放路径,这里我是单独添加一个目录来存放的
log-bin=/var/lib/mysql/mysqld-binlog/mysql-bin.log
#设置要同步的库,这项说明只同步dlp这个数据库
binlog-do-db=ceshi
#
# * Galera-related settings
#
[galera]
# Mandatory settings
#wsrep_on=ON
............
略过
............
4.3.3、配置主库对从库进行授权
在主库对从库授权
MariaDB [(none)]> grant replication slave on *.* to 'slave'@'192.168.1.%' identified by '123123';
MariaDB [(none)]> flush privileges;
注:如果主库没有对登录ip做限制或者没有对安全方面有太大的要求此步骤可以省略。
4.3.4、锁表
MariaDB [(none)]>
MariaDB [(none)]> flush tables with read lock;
4.3.5、重启数据库
[root@TCmysqlone mysql]# systemctl restart mariadb.service
[root@TCmysqlone mysql]#
4.3.6、查看当前二进制日志名和偏移量值
MariaDB [(none)]> show master status;
4.3.7、备份数据库到从库
此项在如果主库有一定的数据,但从库没有数据时,使用此步骤。
使用mysqldump备份主库数据,把备份的数据复制到从库上面,在把数据导入从库即可。对于新装数据库,没有做任何操作的可以省去此步骤。
4.4、修改从数据库配置文件
4.4.1、修改从库配置文件
注:此项基本和配置主库配置是相同的
4.4.2、重启数据库
[root@TCmysqltwo my.cnf.d]# systemctl restart mariadb.service
[root@TCmysqltwo my.cnf.d]#
4.4.3、进行主从复制配置
MariaDB [(none)]> change master to master_host='192.168.10.148',master_port=3306,master_user='cirrus',master_password='gofinger01',master_log_file='mysql-bin.000001',master_log_pos=328;
Query OK, rows affected (.053 sec)
MariaDB [(none)]>
注意:执行指定更新点时,一定要在同步进程没有启动时才可以操作
master_host表示是主库的IP
master_user表示主库master上允许同步的用户
maser_password表示同步用户的密码
master_log_file表示从哪个binlog数据库日志文件开始同步
master_log_pos表示从该binlog文件的那个pos节点位置(偏移量)开始同步.
注意:master_log_file和master_log_pos,就是我们在第四步记录的binlog文件名和pos位置节点
4.4.4、开启同步进程
MariaDB [(none)]> start slave;
Query OK, rows affected (.001 sec)
MariaDB [(none)]>
4.4.5、查看是否同步成功
MariaDB [(none)]> start slave
注:
Slave_IO_Running : Yes | 网络连接正常 |
Slave_SQL_Running:Yes | 数据库结构正常 |
1. Master_host 指的是主服务器的地址。
2. Master_user 指的是主服务器上可以操作的用户,从服务器会用此账号来登录主服务进行复制。
3. Master_log_file主服务器上的日志文件.
4. Read_Master_log_pos主服务器的日志记录位置,从服务器根据这两个条件来选择复制的文件和位置。
5. Slave_IO_Running: 指的就是从服务器上负责读取主服务器的线程工作状态,从服务器用这个专门的线程链接到主服务器上把日志拷贝回来。
6. Slave_SQL_Running: 指的就是专门执行sql的线程,它负责把复制回来的Relaylog执行到自己的数据库中。这两个参数必须都为Yes 才表明复制在正常工作。
4.5、解锁主库
在主库上面使用unlock tables;进行解锁表。解锁的目的就是可以对主库进行写操作。
五、测试
5.1、创建一个测试库表
MariaDB [dlp]> create table ceshi(id int(11));
Query OK, rows affected (.042 sec)
MariaDB [dlp]> desc ceshi;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (.002 sec)
5.2、在从库查看状态和是否同步成功
MariaDB [(none)]> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.10.148
Master_User: cirrus
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 466
Relay_Log_File: TCmysqltwo-relay-bin.000002
Relay_Log_Pos: 693
Relay_Master_Log_File: mysql-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:
Last_Error:
Skip_Counter:
Exec_Master_Log_Pos: 466
Relay_Log_Space: 1007
Until_Condition: None
Until_Log_File:
Until_Log_Pos:
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master:
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno:
Last_IO_Error:
Last_SQL_Errno:
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_SSL_Crl:
Master_SSL_Crlpath:
Using_Gtid: No
Gtid_IO_Pos:
Replicate_Do_Domain_Ids:
Replicate_Ignore_Domain_Ids:
Parallel_Mode: conservative
SQL_Delay:
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
Slave_DDL_Groups: 1
Slave_Non_Transactional_Groups:
Slave_Transactional_Groups:
1 row in set (0.000 sec)
5.2.2、查看是否同步成功
MariaDB [dlp]> desc ceshi;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (.001 sec)
总结:
通过在从库上查看主库的同步状态,发现刚在主库上创建的表已经在从库上显示,说明从库已经同步成功。
六、常见问题
6.1、Slave_IO_Running: NO
一般的原因是:
1、 master服务器的网络不通,或者master服务器的防火墙拒绝了外部连接3306端口,selinux模式选择都可能会影响结果。
2、在配置slave服务器时,使用chage master语句时输错了ip地址和密码等信息。
3、在master主服务器授权了错误的IP地址,权限。
解决方法:
1、关闭防火墙或开通3306的访问权限,selinux设置为disabled;
2、slave的服务器上使用master授权用户登陆一下master数据库确保授权和slave地址能够访问,后slave库检查一下change master语句是否有误;
6.2 Slave_SQL_Running: No
mysql同步故障原因:
1、程序可能在slave上进行了写操作
2、也可能是slave机器重起后,事务回滚造成的.
一般是事务回滚造成
解决方法1:
mysql> stop slave;
mysql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
mysql> start start;
备注:不一定会生效,操作两次不生效后,选择第二种方法
解决方法2:
mysql> stop slave;
mysql> show master status;
master服务器上查看主机状态,记录File和Position对应的值,然后到slave服务器上执行手动同步(change master语句),参考同步时使用的语句。
备注:强制从某一个点同步,这种方法会停掉master写操作,会丢失部分没有同步的数据,不影响使用。
来源 https://mp.weixin.qq.com/s/zdZyT_lkpaMdWXlgBb8dVg