MySQL高级篇(下)

三、查询截取分析

总结步骤:

  1. 慢查询的开启并捕获
  2. explain+慢SQL分析
  3. show profile查询SQL在MySQL服务器里面的执行细节和生命周期情况
  4. SQL数据库服务器的参数调优

3.1 查询优化

3.1.1 小表驱动大表

优化引出

永远小表驱动大表,类似嵌套循环Nested Loop

for(int i = 5...){
    
    
	for(int j = 1000...){
    
    
        
    }
}
===========================
for(int i = 1000...){
    
    
	for(int j = 5...){
    
    
        
    }
} 

两种方式都能达到效果,只不过推荐上面的方式,在MySQL中,如果是需要两张表驱动的话,那么第一种方式只需要连接5次,而第二种方式需要连接1000次

优化原则:小表驱动大表,即小的数据集驱动大的数据集

在这里插入图片描述

EXISTS

  • SELECT … FROM table WHERE EXISTS(subquery)
    该语法可以理解为:将主查询的数据,放到子查询中做条件验证,根据验证结果(TRUE或FALSE)来决定主查询的数据结果是否得以保留
  • 提示
    • EXISTS(subquery)只返回TRUE或FALSE,因此子查询中的SELECT *也可以是SELECT 1或SELECT ‘X’,官方说法是实际执行时会忽略SELECT清单,因此没有区别。
    • EXISTS子查询的实际执行过程可能经过了优化而不是我们理解上的逐条对比,如果担心效率问题,可进行实际检验以确定是否有效率问题。
    • EXISTS子查询往往也可以用条件表达式/其他子查询或者JOIN来替代,何种最优需要具体问题具体分析。

小结

在这里插入图片描述

3.1.2 ORDER BY关键字优化

建表SQL

create table tblA(    age int,    birth timestamp not null);insert into tblA(age,birth) values(22,now());insert into tblA(age,birth) values(23,now());insert into tblA(age,birth) values(24,now());
  • case 1:

    在这里插入图片描述

  • case 2:

    在这里插入图片描述

结论

  • 由case可知在order by的字段顺序中,如果和索引创建的顺序一样,不丢火车头,不断中间字段,都不会出现filesort,特别的,索引从创建默认是升序, 如果排序降序会出现fileosort
  • MySQL支持二种方式的排序,FileSort和Index,Index效率高,它指MySQL扫描索引本身完成排序。FileSort方式效率较低

Order By满足两情况,会使用Index方式排序

  • ORDER BY语句使用索引最左前列
  • 使用Where子句与Order By子句条件列满足索引最左前列

尽可能在索引列上完成排序操作,遵照索引建的最佳最前缀

如果不在索引列上,filesort有两种算法:mysql就要启动双路排序和单路排序

  • 双路排序
    • MySQL4.1之前是使用双路排序,字面意思就是两次扫描磁盘,最终得到数据。读取行指针和order by列,对他们进行排序,然后扫描已经排好序的列表,按照列表中的值重新从列表中读取对应的数据输出。
    • 从磁盘取排序字段,在buffer进行排序,再从磁盘读取其他字段。

取一批数据,要对磁盘进行了两次扫描,众所周知,I\O是很耗时的,所以在mysql4.1之后,出现了第二种改进的算法,就是单路排序


  • 单路排序
    • 从磁盘读取查询需要的所有列,按照order by列在buffer对它们进行排序,然后扫描排序后的列表进行输出,它的效率更快一些,避免了第二次读取数据。并且把随机IO变成了顺序IO,但是它会使用更多的空间。

结论及引申出的问题

单路排序的问题:在sort_ buffer中, 方法B比方法A要多占用很多空间,因为方法B是把所有字段都取出,所以有可能取出的数据的总大小超出了sort_ buffer的容量, 导致每次只能取sort_ buffer容量大小的数据,进行排序(创建tmp文件, 多路合并),排完再取sort_ buffer容量大小,再排…从而多次I/O。本来想省一次I/O操作, 反而导致了大量的I/O操作, 反而得不偿失。

优化策略

  • 增大sort_buffer_size参数的设置
  • 增大max_length_for_sort_data参数的设置

优化策略的解释

在这里插入图片描述

小总结

为排序使用索引

  • MySQL两种排序方式:文件排序或扫描有序索引排序
  • MySQL能为排序与查询使用相同的索引
KEY a_b_c(a,b,c);

order by 能使用最左前缀
- ORDER BY a
- ORDER BY a,b
- ORDER BY a,b,c
- ORDER BY a DESC,b DESC,c DESC

如果WHERE使用索引的最左前缀定义为常量,则orfer by能使用索引

- WHERE a = const ORDER BY b, c
- WHERE a = const AND b = const ORDERBY c
- WHERE a = const ORDER BY b, c
- WHERE a = const AND b > const ORDERBY b, c

不能使用索引进行排序
- ORDER BY a ASC, b DESC, c DESC /* 排序不一致*/
- WHERE g = const ORDER BY b,c /* 丢失a索引*/
- WHERE a = const ORDER BY c /* 丢失b素引*/
- WHERE a = const ORDER BY a,d /* d不是素引的一部分*/
- WHERE a in (...) ORDER BY b,c /* 对于排序来说,多个相等条件也是范围查询*/

3.1.3 GROUP BY 关键字优化

  • group by实质是先排序后进行分组,遵照索引建的最佳左前缀。
  • 当无法使用索引列,增大max_length_for_sort_data参数的设置+增大sort_buffer_size参数的设置。
  • where高于having,能写在where限定的条件就不要去having限定了。

3.2 慢查询日志

3.2.1 是什么

  • MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阈值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。
  • long_query_time的默认值是10,意思是运行10秒以上的语句。
  • 由它来查看哪些SQL超出了我们的最大忍耐时间值,比如一条sql执行超过5秒钟,我们就算慢SQL,希望能收集超过5秒的sql,结合之前的explain进行全面分析。

3.2.2 怎么玩

慢查询日志的说明

  • 默认情况下,MySQL数据库没有开启慢查询日志,需要我们手动来设置这个参数
  • 当然,如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响。慢查询日志支持将日志记录写入文件。

查询是否开启及如何开启

  • 查看

    show variables like '%slow_query_log%';
    

    在这里插入图片描述

    默认情况下slow_query_log的值为OFF,表示慢查询日志是禁用的,可以通过设置slow_query_log的值来开启

  • 开启

    set global slow_query_log=1;
    

    在这里插入图片描述

    说明:使用set global slow_query_log=1开启了慢查询日志只对当前数据库有效,且如果MySQL重启后则会失效

    在这里插入图片描述

那么开启了慢查询日志后,什么样的SQL才会记录到慢查询日志里面呢

这个是由参数long_query_time控制的,默认情况下long_query_time的值为10s,可以用命令修改,也可以在my.cnf参数里面修改

查看命令

show variables like '%long_query_time%';

在这里插入图片描述

其中,加入运行时间正好等于long_query_time的情况,并不会被记录下来。也就是说,在mysql源码里是判断大于long_query_time,而非大于等于。

Case

  • 查看当前多少秒算慢

    SHOW VARIABLES LIKE ‘long_query_time%;
    
  • 设置慢的阈值时间

    set global long_query_time=3;
    

    在这里插入图片描述

  • 为什么设置后看不出变化(设置3之后,查询依然显示10)

    • 需要重新连接或新开一个会话才能看到修改值。

    • 或者设置全局参数

      show global variables like ‘long_query_time’;
      
  • 记录慢SQL并后续分析

    先执行select sleep(4)

    在这里插入图片描述

    [root@cVzhanshi ~]# cat /var/lib/mysql/cVzhanshi-slow.log 
    /usr/sbin/mysqld, Version: 5.5.48-log (MySQL Community Server (GPL)). started with:
    Tcp port: 3306  Unix socket: /var/lib/mysql/mysql.sock
    Time                 Id Command    Argument
    # Time: 211015 10:27:45
    # User@Host: [root] @ localhost []
    # Query_time: 4.006637  Lock_time: 0.000000 Rows_sent: 1  Rows_examined: 0
    SET timestamp=1634264865;
    select sleep(4);
    
  • 查询当前系统中有多少条慢查询记录

    show global status like%Slow_queries%;
    

    在这里插入图片描述

配置文件中设置慢查询日志

只需要在my.cnf中配置如下内容:

【mysqlId】下配置:
slow_query_log=1;
slow_query_log_file=/var/lib/mysql/cVzhanshi-slow.log;
long_query_time=3;
log_output=FILE;

3.2.3 日志分析工具mysqldumpslow

在生产环境中,如果要手工分析日志,查找、分析SQL,显然是个体力活,MySQL提供了日志分析工具mysqldumpslow

查看mysqldumpslow的帮助信息

在这里插入图片描述

参数解释

  • s:是表示按照何种方式排序
  • c:访问次数
  • I:锁定时间
  • r:返回记录
  • t:查询时间
  • al:平均锁定时间
  • ar:平均返回记录数
  • at:平均查询时间
  • t:即为返回前面多少条的数据
  • g:后边搭配一个正则匹配模式,大小写不敏感

工作常用参考

  • 得到返回记录集最多的10个SQL

    mysqldumpslow -s r -t 10 /var/lib/mysql/cVzhanshi-slow.log
    
  • 得到访问次数最多的10个SQL

    mysqldumpslow -s c -t 10 /var/lib/mysql/cVzhanshi-slow.log
    
  • 得到按照时间排序的前10条里面含有左连接的查询语句

    mysqldumpslow -s t -t 10 -g "left join" /var/lib/mysql/cVzhanshi-slow.log
    
  • 另外建议在使用这些命令时结合 | 和 more 使用,否则可能出现爆屏情况

    mysqldumpslow -s r -t 10 /var/lib/mysql/cVzhanshi-slow.log| more
    

3.3 批量数据脚本

准备工作

  • 设置参数log_bin_trust_function_creators

    show variables like 'log_bin_trust_function_creators';set global log_bin_trust_function_creators=1;
    

    在这里插入图片描述

    说明:这样添加了参数以后,如果mysqlId重启,上述参数又会消失

    永久方法:在配置文件中[mysqlId]下加上log_bin_trust_function_creators=1

建表SQL

create table dept(id int unsigned primary key auto_increment,deptno mediumint unsigned not null default 0,dname varchar(20) not null default "",loc varchar(13) not null default "")engine=innodb default charset=GBK;CREATE TABLE emp(id int unsigned primary key auto_increment,empno mediumint unsigned not null default 0,ename varchar(20) not null default "",job varchar(9) not null default "",mgr mediumint unsigned not null default 0,hiredate date not null,sal decimal(7,2) not null,comm decimal(7,2) not null,deptno mediumint unsigned not null default 0)ENGINE=INNODB DEFAULT CHARSET=GBK;

编写函数

/* 函数 随机产生字符串*/delimiter $$create function rand_string(n int) returns varchar(255)begindeclare chars_str varchar(100) default 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';declare return_str varchar(255) default '';declare i int default 0;while i < n doset return_str = concat(return_str,substring(chars_str,floor(1+rand()*52),1));set i=i+1;end while;return return_str;end $$/* 函数 随机产生部门编号 */delimiter $$create function rand_num() returns int(5)begindeclare i int default 0;set i=floor(100+rand()*10);return i;end $$/* 如果要删除 */drop function function_name;

编写存储过程

//存储过程delimiter $$ create procedure insert_emp(in start int(10),in max_num int(10))begindeclare i int default 0;set autocommit = 0;repeatset i = i+1;insert into emp(empno,ename,job,mgr,hiredate,sal,comm,deptno) values((start+i),rand_string(6),'salesman',0001,curdate(),2000,400,rand_num());until i=max_numend repeat;commit;end $$//存储过程delimiter $$ create procedure insert_dept(in start int(10),in max_num int(10))begindeclare i int default 0;set autocommit = 0;repeatset i = i+1;insert into dept(deptno,dname,loc) values((start+i),rand_string(10),rand_string(8));until i=max_numend repeat;commit;end $$

调用过程

  • dept

    DELIMITER ;CALL insert_dept(100, 10);
    
  • emp

    DELIMITER ;CALL insert_emp(100001, 500000);
    

3.4 Show Profile

  • Show Profile:是MySQL提供可以用来分析当前会话中语句执行的资源消耗情况。可以用于SQL的调优的测量
  • 默认情况下,参数处于关闭状态,并保存最近的15次运行结果

分析步骤

  • 查看开启当前的mysql版本是否支持

    show variables like 'profiling';
    

    在这里插入图片描述

  • 开启功能,默认是关闭的,使用前需要开启(开启之后会在后台默认抓SQL

    set profiling=on;
    

    在这里插入图片描述

  • 运行SQL

    select * from emp group by id%10 limit 150000;select * from emp group by id%20 order by 5;...
    
  • 查询结果

    show profiles;
    

    在这里插入图片描述

    能看到我们所执行的sql,且有执行时间

  • 诊断SQL

    show profile cpu,block io for query 上一步查询的Query_ID;
    
    • 参数说明
      • ALL:显示所有的开销信息
      • BLOCK IO :显示块IO相关开销
      • CONTEXT SWITCHES:上下文切换相关开销
      • CPU:显示CPU相关开销信息
      • IPC:显示发送和接收相关开销信息
      • MEMORY:显示内存相关开销信息
      • PAGE FAULTS:显示页面错误相关开销信息
      • SOURCE:显示和Source_ function, Source_ file,Source_ line相关的开销信息
      • SWAPS:显示交换次数相关开销的信息

    在这里插入图片描述

  • 日常开发需要注意的结论

    • converting HEAP to MyISAM:查询结果太大,内存都不够用了往磁盘上搬了
    • Creating tmp table:创建临时表
      • 拷贝数据到临时表
      • 用完再删除
    • Copying to tmp table on disk:把内存中临时表复制到磁盘,危险!!
    • locked

    在这里插入图片描述

3.5 全局查询日志

配置启用

在MySQL的my.cnf中,设置如下:

# 开启general_log=1# 记录日志文件的路径general_log_file=/path/logfile# 输出格式log_output=FILE

编码启用

set global general_log=1;set global log_output='TABLE';

开启之后,执行的sql语句都会记录到mysql库里的general_log表中

查看

select * from mysql.general_log;

在这里插入图片描述

永远不要在生产环境开启这个功能

四、MySQL锁机制

4.1 概述

定义

锁是计算机协调多个进程并发访问某一资源的机制

在数据库中,除传统的计算资源(如CPU、RAM、/0等)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。

举例

生活购物

在这里插入图片描述

锁的分类

  • 从对数据操作的类型(读/写)分
    • 读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响。
    • 写锁(排它锁):当前写操作没有完成前,它会阻断其他写锁和读锁。
  • 从对数据操作的粒度分
    • 表锁
    • 行锁

4.2 三锁

4.2.1 表锁(偏读)

特点

偏向MyISAM存储引擎,开销小,加锁快;无死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低

案例分析

建表SQL

create table mylock (id int not null primary key auto_increment,name varchar(20) default '') engine myisam;insert into mylock(name) values('a');insert into mylock(name) values('b');insert into mylock(name) values('c');insert into mylock(name) values('d');insert into mylock(name) values('e');
  • 手动增加表锁

    lock table mylock read,book write;
    
  • 查看表上加过的锁

    show open tables;
    

    在这里插入图片描述

  • 释放表

    unlock tables;
    

加读锁

session_1(锁表session) session_2
在session_1中对表加读锁 连接终端
当前session可以查询该表记录 其他session也可以查询该表记录
当前session不能查询其他表的记录 其他session可以查询其他表的记录
当前session中插入或者更新锁定的表都会提示错误 其他session插入或者更新锁定的表会进入阻塞状态,一直等待获得锁
释放锁 session_2得到锁,插入操作完成

加写锁

session_1(锁表session) session_2
获得表mylock的WRITE锁定 待Session开启写锁后,session_2再连接终端
当前session对锁定表的查询、更新、插入操作都可以执行 其他session对锁定表的查询会被阻塞,需要等待锁被释放
备注:如果可以,查询sql换一下,因为MySQL有缓存,第二次查询条件会从缓存中取得
释放锁 查询操作完成

案例结论

  • MyISAM在执行查询语句(SELECT) 前,会自动给涉及的所有表加读锁,在执行增删改操作前,会自动给涉及的表加写锁
  • 对MyISAM表的读操作(加读锁),不会阻塞其他进程对同一表的读请求,但会阻塞对同一表的写请求。只有当读锁释放后,才会执行其它进程的写操作。
  • 对MyISAM表的写操作(加写锁),会阻塞其他进程对同一表的读和写操作,只有当写锁释放后,才会执行其它进程的读写操作

简而言之,就是读锁会阻塞写,但是不会堵塞读。而写锁则会把读和写都堵塞

表锁分析

  • 看看哪些表被加锁了

    show open tables;
    
  • 如何分析表锁定:可以通过检查table_locks_waited和table_locks_immediate状态变量来分析系统上的表锁定。

    show status liketable%;
    

    这里有两个状态变量记录MySQL内部表级锁定的情况,两个变量的说明如下:
    Table_locks_immediate:产生表级锁定的次数,表示可以立即获取锁的查询次数,每立即获取锁值加1;
    Table_locks_waited:出现表级锁定争用而发生等待的次数(不能立即获取锁的次数,每等待一次锁值加1),此值高则说明存在着较严重的表级锁争用情况。

此外,MyISAM的读写锁调度是写优先,这也是MyISAM不适合做写为主表的引擎。因为写锁后,其他线程不能做任何操作,大量的更新会使查询很难得到锁,从而造成永远阻塞。

4.2.2 行锁(偏写)

特点

  • 偏向Innodb存储引擎,开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率最低,并发度也最高。

  • Innodb与MyISAM的最大不同有两点:

    • 一是支持事务(TRANSACTION)
    • 而是采用了行级锁

案例分析

建表SQL

CREATE TABLE test_innodb_lock (a INT(11),b VARCHAR(16))ENGINE=INNODB;INSERT INTO test_innodb_lock VALUES(1,'b2');INSERT INTO test_innodb_lock VALUES(3,'3');INSERT INTO test_innodb_lock VALUES(4, '4000');INSERT INTO test_innodb_lock VALUES(5,'5000');INSERT INTO test_innodb_lock VALUES(6, '6000');INSERT INTO test_innodb_lock VALUES(7,'7000');INSERT INTO test_innodb_lock VALUES(8, '8000');INSERT INTO test_innodb_lock VALUES(9,'9000');INSERT INTO test_innodb_lock VALUES(1,'b1');CREATE INDEX test_innodb_a_ind ON test_innodb_lock(a);CREATE INDEX test_innodb_lock_b_ind ON test_innodb_lock(b);select * from test_innodb_lock;SET autocommit=0;

行锁定的基本演示

Session_1 Session_2
SET autocommit=0; SET autocommit=0;
更新记录1但是不提交,还没手动commit Session_2要更新记录1会被阻塞,只能等待
提交更新 解除阻塞,更新正常执行
更新记录1但是不提交,还没手动commit 更新记录9但是不提交,还没手动commit,不影响,因为操作不同行

说明:由于我们把两个session的autocommit都设置为0,所有会出现,session_1进行update后,session_2查询会看不到更新的值,需要commit后才能看见,这个不是错误,是由于我们为了测试把autocommit都设置为0导致的。

无索引行锁升级为表锁

如果在更新数据的时候出现了强制类型转换导致索引失效,使得行锁变表锁,即在操作不同行的时候,会出现阻塞的现象

示例:

建表时给a,b都创建了索引

正确的

在这里插入图片描述

错误的,导索引失效,行锁变表锁

在这里插入图片描述

间隙锁危害

  • 什么是间隙锁:当我们用范围条件而不是相等条件索引数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)”。InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(Next-Key锁)

  • 危害

    • 因为Query执行过程中通过范围查找的话,会锁定整个范围内所有的索引键值,即使这个键值并不存在
    • 间隙锁有一个比较致命的弱点,就是当锁定一个范围键值之后,即使某些不存在的键值也会被无辜的锁定,而造成在锁定的时候无法插入锁定键值范围内的任何数据。在某些场景下这可能会对性能造成很大的危害。

示例

在这里插入图片描述

如何锁定一行

在这里插入图片描述

案例结论

  • InnoDB存储引擎由于实现了行级锁定,虽然在锁定机制的实现方面所带来的性能损耗可能比表级锁定会更高一些,但是在整体并发处理能力方面要远远优于MyISAM的表级锁定的。当系统并发量较高的时候,InnoDB的整体性能和MyISAM相比就会有比较明显的优势了。
  • 但是,InnoDB的行级锁定同样也有其脆弱的一面,当我们使用不当的时候,可能会让InnoDB的整体性能表现不仅不能比MyISAM高,甚至可能会更差。

行锁分析

通过检查InnoDB_row_lock状态变量来分析系统上的行锁的争夺情况

show status like ‘innodb_row_lock%;

在这里插入图片描述

参数说明

  • Innodb_row_lock_current_waits:当前正在等待锁定的数量;
  • innodb_row_lock_time:从系统启动到现在锁定总时间长度;
  • innodb_row_lock_time_avg:每次等待所花平均时间;
  • innodb_row_lock_time_max:从系统启动到现在等待最长的一次所花的时间;
  • innodb_row_lock_waits:系统启动后到现在总共等待的次数。

比较重要的参数

  • innodb_row_lock_time_avg(等待平均时长)
  • innodb_row_lock_waits(等待总次数)
  • innodb_row_lock_time(等待总时长)

这三项,尤其是当等待次数很高,而且每次等待时长也不小的时候,我们就需要分析系统中为什么会有如此多的等待,然后根据分析结果着手制定优化计划。

优化建议

  • 尽可能让所有数据检索都通过索引来完成,避免无索引行锁升级为表锁。
  • 合理设计索引,尽量缩小锁的范围。
  • 尽可能减少索引条件,避免间隙锁。
  • 尽量控制事务大小,减少锁定资源量和时间长度。
  • 尽可能低级别事务隔离。

页锁

  • 开销和加锁时间介于表锁和行锁之间。
  • 会出现死锁。
  • 锁定粒度介于表锁和行锁之间。
  • 并发度一般。

五、主从复制

复制的基本原理

  • slave会从master读取binlog来进行数据同步

  • 三步骤+原理图

    • master将改变记录到二进制日志(binary log)。这些记录过程叫做二进制日志事件,binary log events;
    • slave将master的binary log events拷贝到它的中继日志(relay log) ;
    • slave重做中继日志中的事件,将改变应用到自己的数据库中。MySQL复制是异步的且 串行化的

    在这里插入图片描述

复制的基本原则

  • 每个slave只有一个master
  • 每个slave只能有一个唯一的服务器ID
  • 每个master可以有多个slave

复制的最大问题

  • 延时

一主一从常见配置

  • mysql版本一致且后台以服务运行

  • 主从都配置在[mysqld]结点下,都是小写

  • 主机修改my.ini配置文件

    • 【必须】主服务器唯一ID

      • server-id=1
    • 【必须】启用二进制日志

      • log-bin=自己本地的路径/mysqlbin

        在这里插入图片描述

    • 【可选】启用错误日志

      • log-err=自己本地的路径/mysqlerr

        在这里插入图片描述

    • 【可选】根目录

      • basedir=自己本地路径

        在这里插入图片描述

    • 【可选】临时目录

      • temdir=自己本地路径

        在这里插入图片描述

    • 【可选】数据目录

      • datadir=自己本地路径/Data/

        在这里插入图片描述

    • read-only=0

      • 主机,读写都可以
    • 【可选】设置不要复制的数据库

      • binlog-ignore-db=mysql
    • 【可选】设置需要复制的数据库

      • binlog-do-db=需要复制的主数据库名字
  • 从机修改my.cnf配置文件

    • 【必须】从服务器唯一ID
      • server-id=2
    • 【可选】启用二进制日志
  • 因修改过配置文件,请主机+从机都重启后台mysql服务

  • 主机从机都关闭防火墙

    • windows手动关闭
    • 关闭虚拟机linux防火墙:service iptables stop
  • 在Windows主机上建立账户并授权slave

    • 运行命令

      GRANT REPLICATION SLAVE ON *.* TO 'zhangsan【账号】' @ '192.168.14.167【从机数据库IP】' IDENTIFIED BY '123456'【密码】;
      
    • 刷新数据库:flush privileges;

    • 查询master的状态:show master status;

      在这里插入图片描述

    • 记录下File和Position的值

    • 执行完此步骤后不要再操作主服务器MYSQL,防止主服务器状态值变化

  • 在Linux从机上配置需要复制的主机

    CHANGE MASTER TO MASTER_HOST='主机IP', MASTER_USER='zhangsan', MASTER_PASSWORD='123456', MASTER_LOG_FILE='file名字',MASTER_LOG_POS=position数字;
    

    在这里插入图片描述

  • 启动从服务器复制功能:start slave;

  • show slave status\G【\G是为了以键值的形式显示,好看一些】

    • 下面两个参数都是Yes,则说明主从配置成功!

    • Slave_IO_Running:Yes

    • Slave_SQL_Running:Yes

      在这里插入图片描述

  • 主机新建库、新建表、insert记录,从机复制,然后发现从机也有着些数据了

  • 如何停止从服务复制功能:stop slave;

猜你喜欢

转载自blog.csdn.net/qq_45408390/article/details/121638429