问题引入
1.主服务器主动通知从服务器来拿二进制日志,还是从服务器隔一段时间来拿二进制日志?
主服务器主动通知从服务器来拿二进制日志
2.主服务器如何知道从服务器上有哪些数据
根据位置号
3.是否任何一台机器都可以充当从服务器
不是
4.从服务器如何知道他的主服务器呢?
master-info文件里记录了主服务器的信息
5.master-info文件的作用
记录master的ip,连接过去复制二进制日志的账号和密码,二进制日志文件的名字和位置号
6.relay-log.info文件的作用
告诉SQL thread 读取中继日志
主从复制的原理
1.首先在master上开启二进制日志功能
2.master上数据发生变化,进行DML操作的时候,会产生二进制日志
3.master上的dump线程会通知slave上的IO线程来拿二进制日志,IO线程拿到二进制日志后会写入到slave上的中继日志,然后SQL线程会去读取新产生的中继日志,重演二进制日志里的操作,从而达到slave和master上的数据一模一样,实现数据的一致性。
作用:高可用,负载均衡,备份
主从复制的模式
异步复制(常见的主从复制)
过程
缺点:有延迟,会丢失数据
主主复制
2台主机都是master,业务数据同时往2台机器上写,机器的使用率会提升
给写入的表设置不同的起始值相同的偏移量
若主主双方都操作,最好设置auto-increment-offset 和 auto-increment-increment,以避免冲突。若只在其中一个库操作,可不需要设置
set global auto_increment_increment = 2;
set global auto_increment_offset = 1;
set global auto_increment_increment = 2;
set global auto_increment_offset = 2;
failover:故障转移、故障切换
主从切换
什么时候需要主从切换,主从切换如何实现?
主服务器挂了,需要提升原来的从为主 --》主从切换
完全手工去操作:
步骤:
1.stop slave
2.reset master
3.开启二进制日志
4.建立授权复制的用户
5.再启动一台机器做从,配置master信息去拉取二进制日志
如何将网站的写的流量切到新的master上?
1.直接修改web里的代码里的ip,换成新的master的ip
2.修改域名对应的ip为新的master的ip
3.如果使用中间件,需要在中间件里调整
是否可以自动实现主从切换?
可以
使用脚本实现
1.监控master
在另外一台机器扫描端口:nc 3306
直接访问: mysql -h ip -uroot -p'**' -e 'show databases;'
每秒钟监控一次
2.马上执行手工操作的步骤,脚本自动执行
在线主从复制如何实现?
xtrabackup 解决了备份的时候自动记录二进制日志文件和位置号
半同步复制
先写日志,再写数据
rpl_semi_sync_master_timeout, the value N is given in milliseconds. The default value is 10000 (10 seconds).
如果ack确认包在10秒钟内没有送达,master会启用异步模式
需要安装插件
root@(none) 15:37 mysql>INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
root@(none) 15:59 mysql>SET GLOBAL rpl_semi_sync_master_enabled = 1;
root@(none) 16:02 mysql>show variables like "%semi_sync%";
+-------------------------------------------+------------+
| Variable_name | Value |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled | ON |
| rpl_semi_sync_master_timeout | 10000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_for_slave_count | 1 |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set (0.01 sec)
root@(none) 15:37 mysql>INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
root@(none) 16:03 mysql>SET GLOBAL rpl_semi_sync_slave_enabled =1;
Query OK, 0 rows affected (0.00 sec)
root@(none) 16:03 mysql>show variables like "%semi_sync%";
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | ON |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------+-------+
2 rows in set (0.02 sec)
重启io线程
同步复制
组复制(group replication)
最低3台,最多9台
延迟备份
为什么需要延迟备份?
可以快速的恢复数据,比使用全备+二进制日志恢复更加快些
配置
root@(none) 16:37 mysql>stop slave;
Query OK, 0 rows affected (0.00 sec)
root@(none) 16:37 mysql>CHANGE MASTER TO MASTER_DELAY = 10;
Query OK, 0 rows affected (0.02 sec)
root@(none) 16:37 mysql>start slave;
Query OK, 0 rows affected (0.00 sec)
1主多从,再级联
log-slave-updates=on
但是当我们需要实现级联同步时,即以这样的一个模式,A>B>C实现三级同步时,AB库除了需要设置log-bin参数还需要添加一个参数:log-slave-updates
log-slave-updates参数默认时关闭的状态,如果不手动设置,那么bin-log只会记录直接在该库上执行的SQL语句,由replication机制的SQL线程读取relay-log而执行的SQL语句并不会记录到bin-log,那么就无法实现上述的三级级联同步。
mysql多实例,简单理解就是在一台服务器上,mysql服务开启多个不同的端口(如3306、3307),运行多个服务进程。这些 mysql 服务进程通过不同的 socket来监听不同的数据端口,进而互不干涉的提供各自的服务。
多实例:就是多个运行起来的mysqld进程,每个进程里运行自己的库,各自为各自的库提供服务。
配置主从复制的异步模式
1.安装好2台MySQL服务器,版本一致 --》环境一致
2.master 上启动二进制日志功能,新建一个授权用户,同时将原始数据备份
create user 'screpl'@'192.168.102.136' identified by '123456sc';
grant replication slave on *.* to 'screpl'@'192.168.102.136';
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;
root@(none) 12:38 mysql>FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (0.01 sec)
root@(none) 12:40 mysql>SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 | 4397 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
[root@master backup]# mysqldump -uroot -pSanchuang1234# --all-databases --master-data > dbdump.db
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@master backup]# scp dbdump.db root@192.168.102.136:/root
scp dbdump.db root@192.168.102.136:/root
3.salve上操作
不需要开启二进制日志,但是需要指定server_id = 2
[root@slave ~]# vim /etc/my.cnf
[mysqld]
socket=/data/mysql/mysql.sock
port = 3306
open_files_limit = 8192
innodb_buffer_pool_size = 512M
character-set-server=utf8
server_id = 2
4.在slave上恢复master导出的原始数据
[root@slave ~]# mysql -uroot -pSanchuang1234# <dbdump.db
# slave备份后master解锁
UNLOCK TABLES;
5.salve上填写master信息
root@(none) 12:56 mysql>change master to master_host='192.168.102.139',
-> master_user='screpl',
-> master_password='123456sc',
-> master_port=3306,
-> master_log_file='mysql-bin.000002',
-> master_log_pos=4397;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
root@(none) 13:05 mysql>show slave status \G;
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: No
Slave_SQL_Running: No
[root@slave ~]# cd /data/mysql/
[root@slave mysql]# ls
master.info relay-log.info
[root@slave mysql]# cat master.info
25
mysql-bin.000002
4397
192.168.102.139
screpl
[root@slave mysql]# cat relay-log.info
7
./slave-relay-bin.000001
4
mysql-bin.000002
4397
0
0
1
root@(none) 13:05 mysql>start slave;
Query OK, 0 rows affected (0.01 sec)
root@(none) 13:09 mysql>show slave status \G;
*************************** 1. row ***************************
Slave_IO_State: Connecting to master
Master_Host: 192.168.102.139
Master_User: screpl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000002
Read_Master_Log_Pos: 4397
Relay_Log_File: slave-relay-bin.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
stop slave;
6.验证
root@(none) 12:59 mysql>create database liu;
Query OK, 1 row affected (0.00 sec)
root@(none) 13:12 mysql>show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| liu |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
root@(none) 13:10 mysql>show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| liu |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
配置主从复制的半同步模式
master上操作
root@wei 13:40 mysql>INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.02 sec)
root@wei 15:34 mysql>set global rpl_semi_sync_master_enabled=1;
Query OK, 0 rows affected (0.01 sec)
root@wei 15:35 mysql>show variables like '%semi_sync%';
+-------------------------------------------+------------+
| Variable_name | Value |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled | ON |
| rpl_semi_sync_master_timeout | 10000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_for_slave_count | 1 |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set (0.00 sec)
slave上操作
root@wei 15:31 mysql>INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.01 sec)
root@wei 15:37 mysql>set global rpl_semi_sync_slave_enabled=1;
Query OK, 0 rows affected (0.00 sec)
root@wei 15:37 mysql>show variables like '%semi_sync%';
+-------------------------------------------+------------+
| Variable_name | Value |
+-------------------------------------------+------------+
| rpl_semi_sync_slave_enabled | ON |
| rpl_semi_sync_slave_trace_level | 32 |
+-------------------------------------------+------------+
8 rows in set (0.00 sec)