mysql-主从复制
Posted 小芃总
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql-主从复制相关的知识,希望对你有一定的参考价值。
目录
1.主从简介
mysql 的主从复制(Replication)至少需要两个MySQL服务(可以是同一台机器,也可以是不同机器之间进行)。
MySQL 数据库的主从复制方案,与使用scp/rsync等命令进行的文件级别复制类似,都是数据的远程传输。只不过MySQL的主从复制是其自带的功能,无需借助第三方工具,而且MySQL的主从复制并不是数据库磁盘上的文件直接拷贝,而是通过逻辑的binlog日志复制到要同步的服务器本地,然后由本地的线程读取日志里面的SQL语句,重新应用到MySQL 数据库中。
1.1 作用
- 可以实时灾备,用于故障切换;
- 读写分离,提供查询服务,实现负载均衡;
- 数据热备,避免影响业务。
1.2 形式
- 一主一从
- 主主复制
- 一主多从---扩展系统读取的性能,因为读是在从库读取的
- 多主一从---5.7开始支持
- 联级复制
2.主从复制原理
1.主数据库服务将所有写操作记录在binlog日志中,并产生log dump线程(接受到从数据库服务的I/O线程请求后将binlog日志发送给IO线程)
2.从服务器MySQL服务生成两个线程,一个是 I/O 线程,另一个是 SQL 线程。
3.从库 I/O 线程去请求主库的binlog日志,并将binlog日志中的文件写入relaylog(中继日志)中
4.从库的 SQL 线程会读取relaylog中的内容,并解析成具体的操作,来实现主从的操作一致,达到最终两个数据库数据一致的目的,这个过程为重放
3.主从配置
开启主从复制时,需使主从数据库数据一致(即全备后在从数据库恢复),否则在主操从库没有的数据时,从库复制功能会受到影响,直到重新设置从库记录主库的日志位置
参数
- 主库参数
参数 | 作用 |
---|---|
binlog | 开启二进制日志记录 |
server-id | 数据库服务唯一标识,主库id小于从库 |
innodb_flush_log_at_trx_commit | 0,表示提交事务后,重做日志不会写入日志文件 1,同步写入日志文件 2,异步写入日志文件 |
innodb_support_xa=1 | 确保二进制日志和innodb数据文件的同步 保证复制环境的数据一致 |
log_bin_index | 二进制日志索引名称 |
binlog_format | 二进制日志的类型 |
binlog_row_image | 二进制镜像保存量 |
binlog_do_db,binlog_ignore_db | 记录在二进制日志中和不记录在二进制日志中 |
replicate_do_db[table] | slave只重放指定的库/表 |
replicate_ignore_db[table] | slave忽略重放指定的库/表 |
replicate_wild_do_table | slave重放满足匹配的表 |
replicate_wild_ignore_table | slave忽略重放满足匹配条件的表 |
binlog_cache_size | 缓存还没刷新到磁盘的binlog日志 |
max_binlog_size | 二进制日志最大值 |
expire_logs_days | 二进制日志被保留的有效期 |
sync_binlog | 二进制日志刷新到磁盘频率 |
binlog_rows_query_log_events | 二进制日志基于行,用来指定额外的信息 |
- 从库参数
参数 | 作用 |
---|---|
relay_log | 从节点中继日志名 |
relay_log_index | 中继日志索引名称 |
replicate_do_db和replicate_ignore_db | 过滤那些会被应用到从节点 |
slave_skip_errors | 自动忽略指定错误,逗号分割 |
slave_exec_mode | 取值IDEMPOTENT,STRICE 是否自动忽略重复主键和主键找不到错误 |
log_slave_updates | 启动从节点的二进制日志 |
relay_log_purge | 如何清除中继日志文件,默认1 自动清理 |
read_only | 从库只读,SUPER权限用户除外 |
super_read_only | SUPER用户设置只读 |
skip_slave_start | 从节点跳过自动开启复制 |
sync_relay_log和sysnc_relay_log_info | 中继日志文件同步频率,默认10000 |
repost_host | 区别不同的从节点,SHOW SLAVE HOSTS查看 |
slave_max_allowed_packet | 从节点的SQL和IO线程允许最大的数据包容量 |
relay_log_recovery | 中继日志自动恢复,从库意外停止后使用 |
master_info_repository | slave master节点信息保留在位置,默认file |
relay_log_info_repository | 从节点信息slave保留在位置,默认file |
3.1主数据库
- vm1(192.168.225.129)
- 主库当前数据
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| wisan_db |
+--------------------+
5 rows in set (0.01 sec)
mysql> show tables from wisan_db;
+--------------------+
| Tables_in_wisan_db |
+--------------------+
| student_info |
+--------------------+
1 row in set (0.00 sec)
mysql> select * from wisan_db.student_info;
+----+-------+------+
| id | name | age |
+----+-------+------+
| 1 | wisan | 18 |
| 2 | fyj | 17 |
| 3 | flora | 19 |
| 4 | wang | 20 |
+----+-------+------+
4 rows in set (0.04 sec)
创建同步账号并授权给从数据库使用
##replication slave 为权限类型
##授权的同时创建用户
mysql> grant replication slave on *.* to ‘repli‘@‘192.168.225.130‘ identified by ‘123456‘;
Query OK, 0 rows affected, 1 warning (0.00 sec)
##查看repli用户的slave权限
mysql> select user,repl_slave_priv from mysql.user where user=‘repli‘;
+-------+-----------------+
| user | repl_slave_priv |
+-------+-----------------+
| repli | Y |
+-------+-----------------+
##刷新
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
配置主数据库
[root@vm1 ~]# vim /etc/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/opt/mysql_data/data
socket=/tmp/mysql.sock
port=3306
pid-file=/opt/mysql_data/data/mysql.pid
user=mysql
skip-name-resolve
symbolic-links=0
server-id=10 ##数据库服务器标识,要求主库的id小于从库
log-bin=mysql-bin ##开启binlog日志
重启服务
[root@vm1 ~]# service mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL.. SUCCESS!
[root@vm1 ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 80 *:3306 *:*
[root@vm1 ~]# ls /opt/mysql_data/data/
auto.cnf ibdata1 ib_logfile1 mysql mysql-bin.index performance_schema vm1.localdomain.err
ib_buffer_pool ib_logfile0 ibtmp1 mysql-bin.000001 mysql.pid sys wisan_db
[root@vm1 ~]#
查看主库状态
- 查看此时主库binlog记录的位置
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)
3.2从数据库
- vm3(192.168.225.130)
配置文件
[root@vm3 ~]# vim /etc/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/opt/mysql_data/data
socket=/tmp/mysql.sock
port=3306
pid-file=/opt/mysql_data/data/mysql.pid
user=mysql
skip-name-resolve
symbolic-links=0
server-id=20 ##数据库服务器标识,从库id大于主库
relay-log=mysql-relay-bin ##启用中继日志
重启数据库服务
[root@vm3 ~]# service mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL.. SUCCESS!
[root@vm3 ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 80 *:3306 *:*
LISTEN 0 128 [::]:22 [::]:*
[root@vm3 ~]# ls /opt/mysql_data/data/
auto.cnf ib_logfile0 mysql sys
ib_buffer_pool ib_logfile1 mysql.pid vm3.localdomain.err
ibdata1 ibtmp1 performance_schema
配置并启动主从复制
mysql> change master to
-> master_host=‘192.168.225.129‘,
-> master_user=‘repli‘,
-> master_password=‘123456‘,
-> master_log_file=‘mysql-bin.000001‘,
-> master_log_pos=154;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
查看从库状态
mysql> show slave status G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.225.129
Master_User: repli
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 154
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes ##yes表示从库io启动成功
Slave_SQL_Running: Yes ##yes表示从库重放功能运行成功
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
......................................................
3.3主从复制测试
查看从库当前数据
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
主库更新数据
## 创建新数据库
mysql> create database country;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| country |
| mysql |
| performance_schema |
| sys |
| wisan_db |
+--------------------+
##创建新表
mysql> use country;
Database changed
mysql> create table id_name(
-> id int not null primary key auto_increment,
-> name varchar(100) not null
-> );
mysql> desc country.id_name;
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(100) | NO | | NULL | |
+-------+--------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> insert into id_name(name) values(‘CHINA‘),(‘The United States‘),(‘The United Kingdom‘),(‘Japan‘);
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from country.id_name;
+----+--------------------+
| id | name |
+----+--------------------+
| 1 | CHINA |
| 2 | The United States |
| 3 | The United Kingdom |
| 4 | Japan |
+----+--------------------+
查看从库是否更新
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| country |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.01 sec)
mysql> show tables from country;
+-------------------+
| Tables_in_country |
+-------------------+
| id_name |
+-------------------+
1 row in set (0.01 sec)
mysql> select * from country.id_name;
+----+--------------------+
| id | name |
+----+--------------------+
| 1 | CHINA |
| 2 | The United States |
| 3 | The United Kingdom |
| 4 | Japan |
+----+--------------------+
4 rows in set (0.00 sec)
在主库更新从库没有的数据
mysql> show tables from wisan_db;
+--------------------+
| Tables_in_wisan_db |
+--------------------+
| student_info |
| student_score |
+--------------------+
2 rows in set (0.00 sec)
mysql> insert into wisan_db.student_info(name,age) value(‘hello‘,null);
Query OK, 1 row affected (0.00 sec)
mysql> select * from wisan_db.student_info;
+----+-------+------+
| id | name | age |
+----+-------+------+
| 1 | wisan | 18 |
| 2 | fyj | 17 |
| 3 | flora | 19 |
| 4 | wang | 20 |
| 5 | hello | NULL |
+----+-------+------+
5 rows in set (0.00 sec)
查看从库数据
- 发现从库在复制时发生错误
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| country |
| mysql |
| performance_schema |
| sys |
+--------------------+
##查看状态
mysql> show slave status G;
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: 1146
Last_Error: Error executing row event: ‘Table ‘wisan_db.student_info‘ doesn‘t exist‘
Skip_Counter: 0
4确保主从数据库数据一致
- 此过程在开启主从复制功能之前完成
4.1主数据库
给数据库加上读锁
- 开启一个终端用于上读锁
- 当退出mysql时表示解锁
mysql> flush tables with read lock;
Query OK, 0 rows affected (0.01 sec)
##其他终端更新数据时会卡住,直到解锁才会继续处理
mysql> insert into wisan_db.student_info(name,age) value(‘world‘,null);
全备主库
[root@vm1 ~]# mysqldump -uroot -p123456 --all-databases > /opt/database-backup/all-20201029.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@vm1 ~]# ls /opt/database-backup/
all-20201029.sql
发送给从数据库
[root@vm1 ~]# scp /opt/database-backup/all-20201029.sql root@192.168.225.130:/root/
root@192.168.225.130‘s password:
all-20201029.sql
解除锁表状态
mysql> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)
mysql> quit
Bye
[root@vm1 ~]#
4.2从数据库
恢复主库全备
[root@vm3 ~]# mysql -uroot -p123456 < /root/all-20201029.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@vm3 ~]# mysql -uroot -p123456
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| country |
| mysql |
| performance_schema |
| sys |
| wisan_db |
+--------------------+
mysql> select * from wisan_db.student_info;
+----+-------+------+
| id | name | age |
+----+-------+------+
| 1 | wisan | 18 |
| 2 | fyj | 17 |
| 3 | flora | 19 |
| 4 | wang | 20 |
| 5 | hello | NULL |
+----+-------+------+
5 rows in set (0.00 sec)
mysql> select * from wisan_db.student_score;
Empty set (0.00 sec)
以上是关于mysql-主从复制的主要内容,如果未能解决你的问题,请参考以下文章