Mysql进击篇-存储引擎、索引、sql优化、视图、锁、innoDb、管理

1.存储引擎

Mysql进击篇-存储引擎、索引、sql优化、视图、锁、innoDb、管理
(1)连接层
最上层是一些客户端和连接服务,主要完成一些类似于连接处理,授权认证、以及相关的安全方案,服务器也会为安全接入的每个客户端验证它所具有的操作权限
(2)服务层
第二层架构主要完成大多数核心服务功能,如sql接口,并完成缓存的查询,sql的分析和优化,部分内置函数的执行,所有跨存储引擎的功能也在这一层实现,如过程、函数等
(3)引擎层
存储引擎真正的负责了mysql中数据的存储和提取,服务器通过api和存储引擎进行通信,不同的存储引擎具有不同的功能,这样我们可以根据自己的需求,来选取合适的存储引擎。
(4)存储层
主要是将数据存储在文件系统之上,并完成与存储引擎的交互。
  • 存储引擎就是存储数据、建立索引、更新/查询数据等技术的实现方式。存储引擎是基于表而不是基于库的,所以存储引擎也可以被称为表引擎。默认存储引擎是InnoDB。
    相关操作:
-- 查询建表语句
show create table account;
-- 建表时指定存储引擎
CREATE TABLE 表名(
    ...

) ENGINE=INNODB;
-- 查看当前数据库支持的存储引擎
show engines;

InnoDB
InnoDB 是一种兼顾高可靠性和高性能的通用存储引擎,在 MySQL 5.5 之后,InnoDB 是默认的 MySQL 引擎。
InnoDB: 如果应用对事物的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询之外,还包含很多的更新、删除操作,则 InnoDB 是比较合适的选择
MyISAM: 如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性、并发性要求不高,那这个存储引擎是非常合适的。
Memory: 将所有数据保存在内存中,访问速度快,通常用于临时表及缓存。Memory 的缺陷是对表的大小有限制,太大的表无法缓存在内存中,而且无法保障数据的安全性

2.索引

(1)性能分析语句的查询频次
查看当前数据库的 INSERT, UPDATE, DELETE, SELECT 访问频次:

SHOW GLOBAL STATUS LIKE 'Com_______';

里面7个下划线

Mysql进击篇-存储引擎、索引、sql优化、视图、锁、innoDb、管理
(2)慢查询日志
慢查询日志记录了所有执行时间超过指定参数(long_query_time 单位 秒 默认10秒)的多有sql语句的日志
Mysql的慢查询日志默认没有开启,需要在mysql的配置文件(/etc/my.conf)中配置如下信息:
#开启mysql慢日志查询开关
show_query_log=1
#设置慢日志的时间为2秒,sql语句执行时间超过2秒,就会视为慢查询,记录慢查询日志
long_query_time=2

配置完成通过以下命令重启mysql进行测试,查看日志文件中记录的信息/var/lib/mysql/localhost-slow.log

systemctl restart mysqld

(3)explain
EXPLAIN 或者 DESC 命令获取 MySQL 如何执行 SELECT 语句的信息,包括在 SELECT 语句执行过程中表如何连接和连接的顺序。
语法:

直接在select语句之前加上关键字 explain / desc
EXPLAIN SELECT 字段列表 FROM 表名 HWERE 条件;

EXPLAIN 各字段含义:

id:select 查询的序列号,表示查询中执行 select 子句或者操作表的顺序(id相同,执行顺序从上到下;id不同,值越大越先执行)
select_type:表示 SELECT 的类型,常见取值有 SIMPLE(简单表,即不适用表连接或者子查询)、PRIMARY(主查询,即外层的查询)、UNION(UNION中的第二个或者后面的查询语句)、SUBQUERY(SELECT/WHERE之后包含了子查询)等
type:表示连接类型,性能由好到差的连接类型为 NULL、system、const、eq_ref、ref、range、index、all
possible_key:可能应用在这张表上的索引,一个或多个
Key:实际使用的索引,如果为 NULL,则没有使用索引
Key_len:表示索引中使用的字节数,该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下,长度越短越好
rows:MySQL认为必须要执行的行数,在InnoDB引擎的表中,是一个估计值,可能并不总是准确的
filtered:表示返回结果的行数占需读取行数的百分比,filtered的值越大越好

  1. 索引

Mysql进击篇-存储引擎、索引、sql优化、视图、锁、innoDb、管理

语法:
创建索引

CREATE [UNIQUE|FULLTEXT] INDEX index_name ON table_name (index_col_name,...);

如果不加 CREATE 后面不加索引类型参数,则创建的是常规索引
查看索引

SHOW INDEX DROM table_name;

删除索引

DROP INDEX index_name ON table_name;

例如:

-- name字段为姓名字段,该字段的值可能会重复,为该字段创建索引
create index idx_user_name on tb_user(name);
-- phone手机号字段的值非空,且唯一,为该字段创建唯一索引
create unique index idx_user_phone on tb_user (phone);
-- 为profession, age, status创建联合索引
create index idx_user_pro_age_stat on tb_user(profession, age, status);
-- 为email建立合适的索引来提升查询效率
create index idx_user_email on tb_user(email);
-- 删除索引
drop index idx_user_email on tb_user;

3.1 最左前缀原则

如果索引关联了多列(联合索引),要遵守最左前缀法则,最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列。
如果跳跃某一列,索引将部分失效(后面的字段索引失效)。

联合索引中,出现范围查询(

Mysql进击篇-存储引擎、索引、sql优化、视图、锁、innoDb、管理
Mysql进击篇-存储引擎、索引、sql优化、视图、锁、innoDb、管理
Mysql进击篇-存储引擎、索引、sql优化、视图、锁、innoDb、管理
Mysql进击篇-存储引擎、索引、sql优化、视图、锁、innoDb、管理
Mysql进击篇-存储引擎、索引、sql优化、视图、锁、innoDb、管理

4.视图

mysql在5.1之后推出视图,本身是一个虚拟表,数据来自于表,通过执行时动态生成。视图可以帮我们使用表的一部分而不是所有的表,另一方面也可以针对不同的用户指定不同的查询视图,比如针对一个公司的销售人员,只想给他看部分数据,而某些特殊的数据,比如采购价格,则不会提供给他,再比如,人员薪酬是敏感字段,只能给某个级别以上人员开放
(暂时没用到以后用到更新)

5、存储过程

存储过程,类似于java中的方法,它是一组预先编译好的sql语句的集合,理解成批处理语句
(暂时没用到以后用到更新)

6、变量、流程控制和游标

6.1 变量

6.1.1 分类

(1)系统变量:全局变量、会话变量
(2)自定义变量:用户变量、局部变量

  • 全局变量:
    描述:服务器层面上的,必须拥有super权限才能为系统变量赋值,作用域为整个服务器,也就是针对于所有连接(会话)有效,但不能跨重启
1、查看所有系统变量
SHOW GLOBAL VARIABLES;

2、查看满足条件的部分系统变量
SHOW GLOBAL VARIABLES LIKE '%char%';

3、查看指定的系统变量的值
SELECT @@global 系统变量名;

4、为某个系统变量赋值
方式一: SET GLOBAL 系统变量名=值;
方式二: SET @@global 系统变量名=值;
  • 会话变量
    描述:服务器为每一个连接的客户端都提供了系统变量,作用域为当前的连接(会话)
1、查看所有系统变量
SHOW 【 SESSION 】 VARIABLES;

2、查看满足条件的部分系统变量
SHOW 【 SESSION 】 VARIABLES LIKE '%char%';

3、查看指定的系统变量的值
SELECT 【 SESSION 】系统变量名;

4、为某个系统变量赋值
SET 【 SESSION 】系统变量名=值;
  • 用户变量
    描述:针对于当前连接(会话)生效
    位置:可以在begin end里面,也可以放在外面
1、声明并赋值
SET @变量名=值; 或
SET @变量名:=值; 或
SELECT @变量名:=值;

2、更新值
方式一:
    SET @变量名=值; 或
    SET @变量名:=值; 或
    SELECT @变量名:=值;
方式二:
    SELECT xxx INTO @变量名 FROM 表;

3、查看值
SELECT @变量名;
  • 局部变量
    描述: 作用域,仅仅在定义它的begin end中有效
    位置:只能放在begin end中,而且只能放在第一句
1、声明并赋值
DECLARE 变量名 类型 【 DEFAULT 值 】;

2、更新值
方式一:
    SET 变量名=值; 或
    SET 变量名:=值; 或
    SELECT @变量名:=值;
方式二:
    SELECT xxx INTO 变量名 FROM 表;

3、查看值
SELECT 变量名;

例子:

#测试:
#方式1:
SET @m1 = 1;
SET @m2 := 2;
SET @sum := @m1 + @m2;

SELECT @sum;
/*输出
+------+
| @sum |
+------+
|    3 |
+---

例如:声明两个变量,求和并打印(分别使用会话变量和局部变量)

#方式1:使用用户变量
SET @m=1;
SET @n=1;

SET @sum=@m+@n;
SELECT @sum;

#方式2:使用局部变量
DELIMITER //
CREATE PROCEDURE add_value()
BEGIN
#局部变量
DECLARE m INT DEFAULT 1;
DECLARE n INT DEFAULT 3;
DECLARE SUM INT;
SET SUM = m+n;
SELECT SUM;
END //
DELIMITER ;

6.2 流程控制

解决复杂问题不可能通过一个sql语句完成,需要执行多个sql操作,流程控制语句的作用就是控制存储过程中sql语句的执行顺序,是我们完成复杂操作必不可少的一部分,只要是执行的程序,流程就分为三大类:

  • 顺序结构:
    程序从上往下依次执行
    条件判断语句:IF语句和CASE语句
  • 分支结构:
    程序按条件进行选择执行,从两条或多条路径中选择一条进行执行
    循环语句:LOOP,WHILE和REPEAT
  • 循环结构
    程序满足一定条件下,重复执行一组语句
    跳转语句:ITERATE和LEAVE
    (1)IF语法结构
IF 表达式1 THEN 操作1
[ELSEIF 表达式2 THEN 操作2]……
[ELSE 操作N]
END IF

根据表达式的结果为TRUE或FALSE执行相应的语句,特点:不同的表达式对应不同的操作,使用在begin end中
举例:声明存储过程”update_salary_by_eid1″,定义IN参数emp_id,输入员工编号。判断该员工薪资如果低于8000元并且入职时间超过5年,就涨薪500元;否则就不变。

DELIMITER //
CREATE PROCEDURE update_salary_by_eid1(IN emp_id INT)
BEGIN
DECLARE emp_salary DOUBLE;
DECLARE hire_year DOUBLE;

SELECT salary INTO emp_salary FROM employees WHERE employee_id = emp_id;

SELECT DATEDIFF(CURDATE(),hire_date)/365 INTO hire_year FROM employees WHERE employee_id = emp_id;

IF emp_salary < 8000 AND hire_year > 5
THEN UPDATE employees SET salary = salary + 500 WHERE employee_id = emp_id;
END IF;

END //
DELIMITER ;

(2)CASE语句结构

#&#x60C5;&#x51B5;&#x4E00;&#xFF1A;&#x7C7B;&#x4F3C;&#x4E8E;switch
CASE &#x8868;&#x8FBE;&#x5F0F;
WHEN &#x503C;1 THEN &#x7ED3;&#x679C;1&#x6216;&#x8BED;&#x53E5;1(&#x5982;&#x679C;&#x662F;&#x8BED;&#x53E5;&#xFF0C;&#x9700;&#x8981;&#x52A0;&#x5206;&#x53F7;)
WHEN &#x503C;2 THEN &#x7ED3;&#x679C;2&#x6216;&#x8BED;&#x53E5;2(&#x5982;&#x679C;&#x662F;&#x8BED;&#x53E5;&#xFF0C;&#x9700;&#x8981;&#x52A0;&#x5206;&#x53F7;)
...

ELSE &#x7ED3;&#x679C;n&#x6216;&#x8BED;&#x53E5;n(&#x5982;&#x679C;&#x662F;&#x8BED;&#x53E5;&#xFF0C;&#x9700;&#x8981;&#x52A0;&#x5206;&#x53F7;)
END [case]&#xFF08;&#x5982;&#x679C;&#x662F;&#x653E;&#x5728;begin end&#x4E2D;&#x9700;&#x8981;&#x52A0;&#x4E0A;case&#xFF0C;&#x5982;&#x679C;&#x653E;&#x5728;select&#x540E;&#x9762;&#x4E0D;&#x9700;&#x8981;&#xFF09;
CASE &#x8BED;&#x53E5;&#x7684;&#x8BED;&#x6CD5;&#x7ED3;&#x6784;2&#xFF1A;

#&#x60C5;&#x51B5;&#x4E8C;&#xFF1A;&#x7C7B;&#x4F3C;&#x4E8E;&#x591A;&#x91CD;if
CASE
WHEN &#x6761;&#x4EF6;1 THEN &#x7ED3;&#x679C;1&#x6216;&#x8BED;&#x53E5;1(&#x5982;&#x679C;&#x662F;&#x8BED;&#x53E5;&#xFF0C;&#x9700;&#x8981;&#x52A0;&#x5206;&#x53F7;)
WHEN &#x6761;&#x4EF6;2 THEN &#x7ED3;&#x679C;2&#x6216;&#x8BED;&#x53E5;2(&#x5982;&#x679C;&#x662F;&#x8BED;&#x53E5;&#xFF0C;&#x9700;&#x8981;&#x52A0;&#x5206;&#x53F7;)
...

ELSE &#x7ED3;&#x679C;n&#x6216;&#x8BED;&#x53E5;n(&#x5982;&#x679C;&#x662F;&#x8BED;&#x53E5;&#xFF0C;&#x9700;&#x8981;&#x52A0;&#x5206;&#x53F7;)
END [case]&#xFF08;&#x5982;&#x679C;&#x662F;&#x653E;&#x5728;begin end&#x4E2D;&#x9700;&#x8981;&#x52A0;&#x4E0A;case&#xFF0C;&#x5982;&#x679C;&#x653E;&#x5728;select&#x540E;&#x9762;&#x4E0D;&#x9700;&#x8981;&#xFF09;

举例:
声明存储过程”update_salary_by_eid4″,定义IN参数emp_id,输入员工编号。判断该员工薪资如果低于9000元,就更新薪资为9000元;薪资大于等于9000元且低于10000的,但是奖金比例为NULL的,就更新奖金比例为0.01;其他的涨薪100元。

DELIMITER //
CREATE PROCEDURE update_salary_by_eid4(IN emp_id INT)
BEGIN
DECLARE emp_sal DOUBLE;
DECLARE bonus DECIMAL(3,2);

SELECT salary INTO emp_sal FROM employees WHERE employee_id = emp_id;
SELECT commission_pct INTO bonus FROM employees WHERE employee_id = emp_id;

CASE
WHEN emp_sal<9000 then update employees set salary="9000" where employee_id="emp_id;" when emp_sal<10000 and bonus is null commission_pct="0.01" else end case; delimiter ; < code></9000>

(3)循环结构之loop
loop循环语句用来重复执行某些语句,loop内的语句一致重复执行直到循环被退出(LEAVE),跳出循环过程。
LOOP语句的基本格式如下:

[loop_label:] LOOP
&#x5FAA;&#x73AF;&#x6267;&#x884C;&#x7684;&#x8BED;&#x53E5;
END LOOP[loop_label]

其中,loop_label表示LOOP语句的标注名称,改参数可以省略

DELIMITER //
CREATE PROCEDURE update_salary_loop(OUT num INT)

BEGIN
DECLARE avg_salary DOUBLE;
DECLARE loop_count INT DEFAULT 0;

SELECT AVG(salary) INTO avg_salary FROM employees;

label_loop:LOOP
IF avg_salary >= 12000 THEN LEAVE label_loop;
END IF;
UPDATE employees SET salary = salary * 1.1;
SET loop_count = loop_count + 1;
SELECT AVG(salary) INTO avg_salary FROM employees;
END LOOP label_loop;
SET num = loop_count;
END //
DELIMITER ;

(4)WHILE循环结构
WHILE语句创建一个带条件判断的循环过程。WHILE在执行语句执行时,先对指定的表达式进行判断,如果为真,就执行循环内的语句。

[while_label:] WHILE &#x5FAA;&#x73AF;&#x6761;&#x4EF6; DO
&#x5FAA;&#x73AF;&#x4F53;
END WHILE

例如:”update_salary_while()”,声明OUT参数num,输出循环次数。存储过程中实现循环给大家降薪,薪资降为原来的90%。直到全公司的平均薪资达到5000结束。并统计循环次数。

DELIMITER //
CREATE PROCEDURE update_salary_while(OUT num INT)
BEGIN
DECLARE avg_sal DOUBLE ;
DECLARE while_count INT DEFAULT 0;

SELECT AVG(salary) INTO avg_sal FROM employees;

WHILE avg_sal > 5000 DO

UPDATE employees SET salary = salary * 0.9;
SET while_count = while_count + 1;

SELECT AVG(salary) INTO avg_sal FROM employees; END WHILE;

SET num = while_count;
END //
DELIMITER ;

(5)REPEAT循环结构
REPEAT语句创建一个带条件判断的循环过程,与WHILE循环不同的是,REPEAT循环首先会执行一次循环,然后在UNTIL中进行表达式判断,如果满足条件就退出,即END REPEAT,如果条件不满足,则会继续执行循环,直到满足退出条件为止
REPEAT语句的基本格式如下:

[repeat_label:] REPEAT
&#x5FAA;&#x73AF;&#x4F53;&#x7684;&#x8BED;&#x53E5;

UNTIL &#x7ED3;&#x675F;&#x5FAA;&#x73AF;&#x7684;&#x6761;&#x4EF6;&#x8868;&#x8FBE;&#x5F0F;
END REPEAT [repeat_label]

例子:update_salary_repeat()”,声明OUT参数num,输出循环次数。存储过程中实现循环给大家涨薪,薪资涨为原来的1.15倍。直到全公司的平均薪资达到13000结束。并统计循环次数。

DELIMITER //
CREATE PROCEDURE update_salary_repeat(OUT num INT)
BEGIN
DECLARE avg_sal DOUBLE ;
DECLARE repeat_count INT DEFAULT 0;
SELECT AVG(salary) INTO avg_sal FROM employees;

REPEAT
UPDATE employees SET salary = salary * 1.15;
SET repeat_count = repeat_count + 1;

SELECT AVG(salary) INTO avg_sal FROM employees;

UNTIL avg_sal >= 13000

END REPEAT;

SET num = repeat_count;

END //
DELIMITER ;

6.3游标

虽然可以通过筛选条件where和having,或者是限定返回记录的关键字LIMIT返回一条数据,但是,却无法在结果集中像指针一样,向前定位一条记录,向后定位一条记录。或者随意定位到某一条记录,并对记录的数据进行处理。
这时候就可以用到游标,能够对结果集中的每一条记录进行定位,并对指向的记录中的数据进行操作的数据结构。
在sql中,游标是一种临时的数据库对象,可以只想存储在数据库中的数据指针,可以通过操作游标对数据进行操作
使用游标的步骤,不同的DBMS语法不同
第一步,声明游标
在mysql中,使用declare关键字来声明游标,其语法的基本形式如下:

DECLARE cursor_name CURSOR FOR select_statement;

如果使用SELECT语句来获取数据结果集,而此时还没有开始遍历数据,这里select_statement代表的是SELECT语句,返回一个用于创建游标的结果集。
比如:

DECLARE cur_emp CURSOR FOR
SELECT employee_id,salary FROM employees;
DECLARE cursor_fruit CURSOR FOR
SELECT f_name, f_price FROM fruits ;

第二步,打开游标
打开游标的语法如下:

OPEN cursor_name

第三步,使用游标(从游标中取得数据)

FETCH cursor_name INTO var_name [, var_name] ...

第四步,关闭游标

LOSE cursor_name

例子:
创建存储过程”get_count_by_limit_total_salary()”,声明IN参数 limit_total_salary,DOUBLE类型;声明OUT参数total_count,INT类型。函数的功能可以实现累加薪资最高的几个员工的薪资值,直到薪资总和达到limit_total_salary参数的值,返回累加的人数给total_count

DELIMITER //
CREATE PROCEDURE get_count_by_limit_total_salary(IN limit_total_salary DOUBLE,OUT total_count INT)
BEGIN
DECLARE sum_salary DOUBLE DEFAULT 0;
#&#x8BB0;&#x5F55;&#x7D2F;&#x52A0;&#x7684;&#x603B;&#x5DE5;&#x8D44;
DECLARE cursor_salary DOUBLE DEFAULT 0;
#&#x8BB0;&#x5F55;&#x67D0;&#x4E00;&#x4E2A;&#x5DE5;&#x8D44;&#x503C;
DECLARE emp_count INT DEFAULT 0;
#&#x8BB0;&#x5F55;&#x5FAA;&#x73AF;&#x4E2A;&#x6570;
#&#x5B9A;&#x4E49;&#x6E38;&#x6807;
DECLARE emp_cursor CURSOR FOR SELECT salary FROM employees ORDER BY salary DESC;
#&#x6253;&#x5F00;&#x6E38;&#x6807;
OPEN emp_cursor;
REPEAT
#&#x4F7F;&#x7528;&#x6E38;&#x6807;&#xFF08;&#x4ECE;&#x6E38;&#x6807;&#x4E2D;&#x83B7;&#x53D6;&#x6570;&#x636E;&#xFF09;
FETCH emp_cursor INTO cursor_salary;
SET sum_salary = sum_salary + cursor_salary;
SET emp_count = emp_count + 1;
UNTIL sum_salary >= limit_total_salary
END REPEAT;
SET total_count = emp_count;

#&#x5173;&#x95ED;&#x6E38;&#x6807;
CLOSE emp_cursor;
END //
DELIMITER ;

6.4触发器

暂时没用到,后续补充

7、索引优化与查询优化

https://blog.csdn.net/IAMLSL/article/details/122853040?spm=1001.2014.3001.5506

8、Mysql主从复制

主从复制允许将来自一个mysql数据库(主服务器)的数据复制到一个或多个mysql数据库服务器(从服务器)

Mysql进击篇-存储引擎、索引、sql优化、视图、锁、innoDb、管理
(1)主节点配置
上图中192.168.206.128为主节点
[root@caochenlei ~]# vi /usr/my.cnf

在[mysqld]下一行添加以下信息

#&#x65E5;&#x5FD7;&#x540D;&#x79F0;
log-bin=mysql-bin
#&#x65E5;&#x5FD7;&#x683C;&#x5F0F;&#xFF1A;row&#x3001;statement&#x3001;mixed
binlog-format=row
#&#x670D;&#x52A1;&#x5668;ID&#x6807;&#x8BC6;
server-id=1
#&#x5237;&#x5199;&#x4E8B;&#x52A1;&#x65E5;&#x5FD7;
innodb_flush_log_at_trx_commit=1
#&#x6267;&#x884C;&#x5199;&#x5165;1&#x6B21;&#x540C;&#x6B65;1&#x6B21;
sync_binlog=1
#&#x53CA;&#x65F6;&#x66F4;&#x65B0;master_info
sync_master_info=1

重启:

[root@caochenlei ~]# service mysql restart
Shutting down MySQL...                                     [&#x786E;&#x5B9A;]
Starting MySQL.....                                        [&#x786E;&#x5B9A;]

连接:

[root@caochenlei ~]# mysql -uroot -p123456

授权:

mysql> grant replication slave on *.* to 'root'@'%' identified by '123456';
Query OK, 0 rows affected (0.03 sec)

刷新:

mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)

查看:

mysql> show master status\G
*************************** 1. row ***************************
             File: mysql-bin.000001
         Position: 397
     Binlog_Do_DB:
 Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)

(2)从节点
192.168.206.129为从节点

[root@caochenlei ~]# vi /usr/my.cnf

在[mysqld]下一行添加以下信息

#&#x65E5;&#x5FD7;&#x540D;&#x79F0;
log-bin=mysql-bin
#&#x65E5;&#x5FD7;&#x683C;&#x5F0F;&#xFF1A;row&#x3001;statement&#x3001;mixed
binlog-format=row
#&#x670D;&#x52A1;&#x5668;ID&#x6807;&#x8BC6;
server-id=2
#&#x662F;&#x5426;&#x53EA;&#x8BFB;
read_only=1

停止:

[root@caochenlei ~]# service mysql stop
Shutting down MySQL..                                      [&#x786E;&#x5B9A;]

删除:
这里不能直接重启mysql是因为它们的auto.cnf中的server-uuid是一样的,在进行接下来的配置的时候会失败,所以要删除从库的server-uuid,让它在启动的时候自动生成一个全新的server-uuid

[root@caochenlei ~]# rm -f /var/lib/mysql/auto.cnf

启动:

[root@caochenlei ~]# service mysql start
Starting MySQL...                                          [&#x786E;&#x5B9A;]

连接:

[root@caochenlei ~]# mysql -uroot -p123456

执行:
注意:MASTER_LOG_FILE=show master status的File、MASTER_LOG_POS=show master status的Position

CHANGE MASTER TO
MASTER_HOST='192.168.206.128',
MASTER_PORT=3306,
MASTER_USER='root',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=397;

开启

mysql> start slave;
Query OK, 0 rows affected (0.03 sec)

查看
注意:重点检查Master_Log_File、Read_Master_Log_Pos是否和主节点的信息一致,Slave_IO_Running、Slave_SQL_Running是否为YES

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.206.128
                  Master_User: root
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 397
               Relay_Log_File: caochenlei-relay-bin.000002
                Relay_Log_Pos: 283
        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: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 397
              Relay_Log_Space: 461
              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
                  Master_UUID: d7200ffb-e698-11ea-87e0-000c29e99cce
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                Auto_Position: 0
1 row in set (0.02 sec)

(3)连接测试
测试连接:192.168.206.128(master)

Mysql进击篇-存储引擎、索引、sql优化、视图、锁、innoDb、管理

创建数据库:

CREATE DATABASE mytest CHARACTER SET utf8 ;

创建数据表:

CREATE TABLE mytest.myuser (
  id BIGINT NOT NULL AUTO_INCREMENT,
  username VARCHAR (20) NOT NULL,
  password VARCHAR (20) NOT NULL,
  PRIMARY KEY (id)
) ;

添加数据

INSERT INTO mytest.myuser (id, username, password) VALUES ('1', 'zhangsan', '123456');
INSERT INTO mytest.myuser (id, username, password) VALUES ('2', 'lisi', '123456');
INSERT INTO mytest.myuser (id, username, password) VALUES ('3', 'wangwu', '123456');

连接测试:192.168.206.129(slave)

Mysql进击篇-存储引擎、索引、sql优化、视图、锁、innoDb、管理
USE mytest;
SELECT * FROM myuser;

我们会发现我们只在192.168.206.128(master)创建数据库、创建表、添加数据,而它的从节点会自动的拉取主节点的内容,这就是所谓的主从复制了。

Original: https://www.cnblogs.com/cgy1995/p/16538639.html
Author: spiderMan1-1
Title: Mysql进击篇-存储引擎、索引、sql优化、视图、锁、innoDb、管理

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/712220/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球