1、将MYSQL主从复制的用途、工作原理、实施注意事项写出来。并且划出主从结构图和把实施的步骤写在文档里面。
2、构建MYSQL主主复制,实现在主库操作增删改,从库能够同步,在从库操作增删改,主库也能同步数据。
1、将MYSQL主从复制的用途、工作原理、实施注意事项写出来。并且划出主从结构图和把实施的步骤写在文档里面。
主从用途:
主从复制,实际上就是用来建立一个和主数据库完全一样的数据库环境,成为从数据库。主库一般是准实时的业务数据库,常用的数据库中,支持单项、异步赋值。一般有三种用途:
1、确保数据安全:做数据的热备,作为后备数据库,主库数据库宕机故障,可以切换到从数据库继续工作,避免数据丢失。
2、提升I/O性能:随着日常生产业务量增大,I/O访问频率越来越高,单机无法满足,做多数据库存储,有效降低磁盘I/O访问的频率,提升了单点设备的性能。
3、实施读写分离:读写分离能使得数据库支持更大的并发。一般根据业务量设计,通常是把主库设置写入,从库设置读取,当用户写入数据,读写分离实施之后,只会写入给主库,不会写入给从库,并且把主库写入的数据同步给从库,而主库不负责用户读取数据的操作。而从库通过异步同步,不负责写入数据,只负责用户读取。分工明确,可以极大的降低主库的压力,不会导致数据库宕机。
工作原理:
1、我们在MySQL中配置了主从之后,只要我们对Master节点进行了写操作,这个操作将会被保存到MySQL的binary-log(bin-log)日志当中。当slave连接到master的时候,master机器会为slave开启binlog dump线程。
2、当master 的 binlog发生变化的时候,Master的dump线程会通知slave,并将相应的binlog内容发送给Slave。
3、而Slave节点在主从同步开启的时候,会创建两个线程,一个I/O线程,一个SQL线程。
I/O线程:该线程链接到master机器,master机器的binlog发送到slave的时候,IO线程会将该日志内容写在本地的中继日志(Relay log)中。
SQL线程:该线程读取中继日志中的内容,并且根据中继日志中的内容对Slave数据库做相应的操作。
真正在其中起到作用的实际上就是这两个日志文件,binlog和中继日志(Relay log)。
##可能造成的问题:在写请求相当多的情况下,可能会造成Slave数据和Master数据不一致的情况,这是因为日志传输过程中的短暂延迟、或者写命令较多,系统速度不匹配造成的。
主从实施注意事项:
配置文件中 /etc/my.cnf
[mysqld] #服务器配置
server-id=1 #主从只能是唯一值
log-bin=jfedu-log #主库开启bin-log模式
#key_buffer_size = 2048MB #MyISAM表索引缓冲区的大小;设置为内存最大值的3/4
#innodb_buffer_pool_size = 2048MB #InnoDB内存缓冲数据和索引大小;设置为内存最大值的3/4
socket=/data/mysql/mysql.sock #socket通信设置,如果是编译安装,一定选择好目录不轻易更改
datadir=/data/mysql #数据目录
拓展
常见的实施环境有以下
1、主从复制
产生问题:主库只要宕机,从库就无法获取数据,导致业务无法正常运转
处理方式:主主复制
2、互为主从
好处:解决主库宕机数据丢失,立刻切换至另一台主服务器。
产生问题:主服务器业务量访问大,导致宕机,切换为另一台服务器,高并发场景,很有可能直接导致另一台服务器也直接宕机。
处理方式:主从从(读写分离)
3、主从从(读写分离)
好处:分工明确,主库写入数据,从库读取数据,降低I/O损耗,增加冗余 ,增加了机器的处理能力, 对于读操作为主的应用,使用读写分离是最好的场景,因为可以确保写的服务器压力更小,而读又可以接受点时间上的延迟。
产生问题:当主库宕机,用户写的请求将会无法写入。
处理方式:主主从从
4、主主从从
好处:当Master01宕机,Master02能正常接入数据,提供服务
产生问题:当Master02宕机,直接导致用户新增数据无法查询(无法写入数据)。
处理方式:使用中间件服务:Mysql-proxy 、Mycat
好处:
1、当Master宕机,通过基于心跳的自动故障切换支持读写分离
2、支持MySQL主从 ,会把任意的Slave变为Master能正常接入数据,继续提供服务。
3、支持前端作为MySQL通用代理,后端JDBC方式支持Oracle、DB2、SQL Server 、 mongodb 。
4、基于Nio实现,有效管理线程,解决高并发问题。
5、支持数据的多片自动路由与聚合
等等
产生问题:
1、Mycat设置连接池多了,对性能有一定冲击。
2、因为是分片式存储,那么备份的话无法全部备份,有可能时间点错开备份,那么会导致数据丢失。或者恢复数据及其困难。
处理方式: Spanner&F1 、SequoiaDB、TiDB
总结:根据公司业务以及业务量,选取最合适的架构。没有最好的方案,只有最合适的方案。
2、构建MYSQL主主复制,实现在主库操作增删改,从库能够同步,在从库操作增删改,主库也能同步数据。
实验环境:
IP | 服务 |
---|---|
192.168.142.104 | mariadb5.5 |
192.168.142.105 | mariadb5.5 |
1、安装mariadb5.5
yum install -y mariadb*
#注意:安装前查看进程以及端口,避免其他版本mysql启动
2、修改配置文件
#192.168.142.104
server-id=1
log-bin=jfedu1-bin-log
#192.168.142.105
server-id=2
log-bin=jfedu2-bin-log
3、启动mariadb并查看数据目录
systemctl start mariadb
ls /var/lib/mysql
#192.168.142.104
aria_log.00000001 ib_logfile1 jfedu1-bin-log.index
aria_log_control jfedu1-bin-log.000001 mysql
ibdata1 jfedu1-bin-log.000002 performance_schema
ib_logfile0 jfedu1-bin-log.000003 test
#192.168.142.105
aria_log.00000001 ib_logfile1 jfedu2-bin-log.index
aria_log_control jfedu2-bin-log.000001 mysql
ibdata1 jfedu2-bin-log.000002 performance_schema
ib_logfile0 jfedu2-bin-log.000003 test
4、登入数据库,创建用户并配置互为主从
1、配置192.168.142.104为主库
#授权
MariaDB [(none)]> grant all privileges on *.* to 'jfedu1'@'192.168.142.%' identified by '123456';Query OK, 0 rows affected (0.00 sec)
#创建库
MariaDB [(none)]> create database jfedu01;
Query OK, 1 row affected (0.01 sec)
#切换库
MariaDB [(none)]> use jfedu01
Database changed
#创建表
MariaDB [jfedu01]> create table student(
-> id int(20) primary key auto_increment,
-> name varchar(20),
-> class varchar(20)
-> );
Query OK, 0 rows affected (0.00 sec)
#查看192.168.142.104为主库时候状态
MariaDB [jfedu01]> show master status;
+-----------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-----------------------+----------+--------------+------------------+
| jfedu1-bin-log.000004 | 726 | | |
+-----------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
#192.168.142.105为从库配置
MariaDB [(none)]> change master to
-> master_host='192.168.142.104',
-> master_user='jfedu1',
-> master_password='123456',
-> master_log_file='jfedu1-bin-log.000004',
-> master_log_pos=726;
Query OK, 0 rows affected (0.01 sec)
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.142.104
Master_User: jfedu1
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: jfedu1-bin-log.000004
Read_Master_Log_Pos: 726
Relay_Log_File: mariadb-relay-bin.000002
Relay_Log_Pos: 534
Relay_Master_Log_File: jfedu1-bin-log.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: 726
Relay_Log_Space: 830
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
1 row in set (0.00 sec)
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
#发现192.168.142.105为从库时候数据没有更新jfedu01的库
#192.168.142.105退出查询sql语句
...
/*!*/;
# at 473
#220429 3:38:32 server id 1 end_log_pos 562 Query thread_id=2 exec_time
=0 error_code=0SET TIMESTAMP=1651174712/*!*/;
create database jfedu01
...
#192.168.142.105关闭主从,并且重新配置主从
MariaDB [(none)]> change master to
-> master_host='192.168.142.104',
-> master_user='jfedu1',
-> master_password='123456',
-> master_log_file='jfedu1-bin-log.000004',
-> master_log_pos=473;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> show slave status \G
...
Relay_Log_File: mariadb-relay-bin.000002
Relay_Log_Pos: 534
Relay_Master_Log_File: jfedu1-bin-log.000004
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: 1007
Last_Error: Error 'Can't create database 'jfedu01'; database e
xists' on query. Default database: 'jfedu01'. Query: 'create database jfedu01' Skip_Counter: 0
Exec_Master_Log_Pos: 473
Relay_Log_Space: 1083
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 1007
Last_SQL_Error: Error 'Can't create database 'jfedu01'; database e
xists' on query. Default database: 'jfedu01'. Query: 'create database jfedu01' Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
1 row in set (0.00 sec)
#发现报错Last_Error: Error 'Can't create database 'jfedu01'; database exists' on query. Default database: 'jfedu01'. Query: 'create database jfedu01'
MariaDB [(none)]> stop slave;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> set global sql_slave_skip_counter=1;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> show slave status \G
...
Read_Master_Log_Pos: 726
Relay_Log_File: mariadb-relay-bin.000002
Relay_Log_Pos: 623
Relay_Master_Log_File: jfedu1-bin-log.000004
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB:
...
Last_SQL_Error: Error 'Table 'student' already exists' on query. D
efault database: 'jfedu01'. Query: 'create table student(id int(20) primary key auto_increment,
name varchar(20),
class varchar(20)
)'
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
1 row in set (0.00 sec)
#发现库建好了,但是表没有创建。所以再停止slave,
MariaDB [(none)]> stop slave;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> set global sql_slave_skip_counter=1;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> set global sql_slave_skip_counter=1;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> show slave status \G
...
Master_Log_File: jfedu1-bin-log.000004
Read_Master_Log_Pos: 726
Relay_Log_File: mariadb-relay-bin.000004
Relay_Log_Pos: 534
Relay_Master_Log_File: jfedu1-bin-log.000004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
...
#再次查询,总算有jfedu01的库,并且IO和sql表示已经启动。说明已经开始同步
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| jfedu01 |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)
#思考:为什么老师能实时同步,我实时同步还是失败?
2、配置192.168.142.105为主库
#授权
grant all privileges on *.* to 'jfedu2'@'192.168.142.%' identif
ied by '123456';
#查看192.168.142.105为主库时候状态
MariaDB [jfedu01]> show master status ;
+-----------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-----------------------+----------+--------------+------------------+
| jfedu2-bin-log.000004 | 473 | | |
+-----------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
#192.168.142.104为从库配置
MariaDB [jfedu01]> change master to
-> master_host='192.168.142.105',
-> master_user='jfedu2',
-> master_password='123456',
-> master_log_file='jfedu2-bin-log.000004',
-> master_log_pos=473;
Query OK, 0 rows affected (0.00 sec)
MariaDB [jfedu01]> start slave;
Query OK, 0 rows affected (0.00 sec)
MariaDB [jfedu01]> show slave status \G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.142.105
Master_User: jfedu2
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: jfedu2-bin-log.000004
Read_Master_Log_Pos: 473
Relay_Log_File: mariadb-relay-bin.000002
Relay_Log_Pos: 534
Relay_Master_Log_File: jfedu2-bin-log.000004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
...
#此刻互为104和105已经互为主从
5、验证双方都互为主从
思路:如果其中一方为从库,那么从从库插入数据,主库的数据不会变动
#104服务器创建jfedu03库
MariaDB [jfedu01]> create database jfedu03;
Query OK, 1 row affected (0.00 sec)
#105服务器查询到jfedu03的库。并创建jfedu06的库
MariaDB [jfedu01]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| jfedu01 |
| jfedu03 |
| mysql |
| performance_schema |
| test |
+--------------------+
6 rows in set (0.00 sec)
MariaDB [jfedu01]> create database jfedu06;
Query OK, 1 row affected (0.00 sec)
#104服务器查询到jfedu06的库
MariaDB [jfedu01]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| jfedu01 |
| jfedu03 |
| jfedu06 |
| mysql |
| performance_schema |
| test |
+--------------------+
7 rows in set (0.00 sec)