mysql系列(七)mysql 主从复制和mysql查询优化

序号 名称 链接地址
1  mysql系列(一) centos7 安装msql https://blog.csdn.net/qq_38130094/article/details/103529535
2 mysql系列(二)mysql简介之逻辑架构/锁粒度/事务/死锁/事务日志/MVCC https://blog.csdn.net/qq_38130094/article/details/103549194
3 mysql系列(三) mysql存储引擎简介 https://blog.csdn.net/qq_38130094/article/details/103599497
4 mysql系列(四) mysql数据库设计优化 https://blog.csdn.net/qq_38130094/article/details/103551778
5  mysql系列(五) mysql索引详细解析及使用 https://blog.csdn.net/qq_38130094/article/details/103553971
6 mysql系列(六)mysql 慢日志查询(pt-query-digest)/如何单条SQL分析和Explain及trace工具 https://blog.csdn.net/qq_38130094/article/details/103551705
7 mysql系列(七)mysql 主从复制和mysql查询优化 https://blog.csdn.net/qq_38130094/article/details/103603586

1. 什么是MySQL主从复制

MySQL数据库自身提供的主从复制功能可以方便的实现数据的多处自动备份,实现数据库的拓展。多个数据备份不仅可以加强数据的安全性,通过实现读写分离还能进一步提升数据库的负载性能。

mysql系列(七)mysql 主从复制和mysql查询优化_第1张图片

2. mysql 的不同复制类型

2.1异步复制

MySQL复制默认是异步复制,Master将事件写入binlog,提交事务,自身并不知道slave是否接收是否处理;这样就会有一个问题,主如果crash掉了,此时主上已经提交的事务可能并没有传到从上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。

缺点:不能保证所有事务都被所有slave接收。

2.2 同步复制

指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端,也就是说Master提交事务,直到事务在所有slave都已提交,才会返回客户端事务执行完毕信息;

缺点:需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。

2.3 半同步复制(半同步复制在5.5后才支持

当Master上开启半同步复制功能时,至少有一个slave开启其功能。当Master向slave提交事务,且事务已写入relay-log中并刷新到磁盘上,slave才会告知Master已收到;若Master提交事务受到阻塞,出现等待超时,在一定时间内Master 没被告知已收到,此时Master自动转换为异步复制机制。

介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。

缺点:

  1. 此时,客户端会收到事务提交失败的信息,客户端会重新提交该事务到新的主上,当宕机的主库重新启动后,以从库的身份重新加入到该主从结构中,会发现,该事务在从库中被提交了两次,一次是之前作为主的时候,一次是被新主同步过来的。
  2. 此时,从库已经收到并应用了该事务,但是客户端仍然会收到事务提交失败的信息,重新提交该事务到新的主上。

3. 配置主从复制(异步复制)

1.Master将改变记录到二进制日志(binary log)中(需开启bin log)

2. Slave将Master的binary log events拷贝(通过IO线程)到它的中继日志(relay log)

3. Slave重做中继日志中的事件,将改变反映它自己的数据

3.1 配置主服务器

1:修改 mysql的 配置文件 my.conf(yum安装在  /etc/my.conf)

server_id MySQL集群唯一编号(唯一标识)

log_bin  二进制日志(bingary log)的选项。指定文件名。

2:重启mysql服务器

systemctl restart mysql

或者下方命令根据自己的服务来重启

systemctl restart mysqld

3: 主机上(master)上建立同步复制的用户并赋权(IP可以使用%表示范围, )

create user 'repl'@'slave主机IP' identified by '123456';

grant replication slave on *.* to 'repl'@'slave主机IP' identified by '123456';

3.2 配置slave服务器,从机上(slave)上建立和主机同步连接

如果主服务器已经有数据需要先手动的把数据导入到从服务器---方式很多自行,dump

#如果作为slave启动过
stop slave;
#执行作为从服务器得命令
#master_host='10.10.10.1' 主服务器的IP
#master_user='repl' 指定在主服务器给的同步的用户名
#MASTER_PASSWORD='123456'  指定用户对应的密码
#MASTER_LOG_FILE='mysql-bin.000001' 指定主服务器的bin日志名
#MASTER_LOG_POS=1818 bin日志起始位置  可以在主服务器使用show master status;查看

change master to master_host='主ip', master_user='repl',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=1818;

#开始命令

start slave;

执行完毕后:

#使用 show slave status \G  查看从服务器的状态

*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event (代表等待主服务器的同步)
                  Master_Host: ###########         (主服务器的IP)
                  Master_User: repl                (同步使用的用户名)
                  Master_Port: 3306                (主服务器的端口) 
                Connect_Retry: 60                  (失败重连间隔) 
              Master_Log_File: mysql-bin.000001    (主服务器的bin log日志名称) 
          Read_Master_Log_Pos: 1818                (读取bin log起始偏移量)
               Relay_Log_File: iZ2zehf3z0yo0vu7y8zj9hZ-relay-bin.000002
                Relay_Log_Pos: 320
        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: 1818
              Relay_Log_Space: 545
              Until_Condition: None

使用 :show binlog events in 'mysql-bin.000001' from 0;  查看bin-log日志

4.查询缓存(mysql5.8已取消)

很多数据库产品都能够缓存查询的执行计划,对于相同类型的SQL就可以跳过SQL解析和执行计划生 成阶段。但是MySQL还有另一种不同的缓存类型:缓存完整的SELECT查询结果,也就是“查询缓存”(在缓存中)。 MySQL查询缓存保存查询返回的完整结果。当查询命中该缓存,MySQL会立刻返回结果,跳过了解 析、优化和执行阶段(还没到存储引擎)。查询缓存系统会跟踪查询中涉及的每个表,如果这些表发生变化,那么和这个表相 关的所有的缓存数据都将失效。

如何判断缓存命中?

MySQL判断缓存命中的方法很简单:缓存存放在一个引用表中,通过一个哈希值引用,这个哈希值包 括了查询SQL本身、当前要查询的数据库、客户端协议的版本等一些其他可能会影响返回结果的信息。 当判断缓存是否命中时,MySQL不会解析查询语句,而是直接使用SQL语句和客户端发送过来的其他 原始信息。任何字符上的不同,例如空格、注释,都会导致缓存的不命中。 当查询语句中有一些不确定的数据时,则不会被缓存。例如包含函数NOW()或者CURRENT_DATE()的 查询不会被缓存。事实上,如果查询中包含任何用户自定义函数、存储函数、用户变量、临时表、mysql 库中的系统表,或者任何包含列级别权限的表,都不会被缓存。

5.查询优化器

6 .特定优化查询

6.1 Order by与Group by优化:

准备工作:

DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
  `id` int(11) NOT NULL,
  `name` varchar(24) DEFAULT NULL,
  `sex` varchar(2) CHARACTER SET latin1 DEFAULT NULL,
  `adress` varchar(24) DEFAULT NULL,
  `project` varchar(24) CHARACTER SET latin1 DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_name_adress` (`name`,`age`,`adress`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tb_user
-- ----------------------------
INSERT INTO `tb_user` VALUES ('1', '小明', '1', '河北', '123456');
INSERT INTO `tb_user` VALUES ('2', '小红', '2', '北京', '31');
INSERT INTO `tb_user` VALUES ('3', '小亮', '1', '天津', '22');
INSERT INTO `tb_user` VALUES ('4', '小红1', '1', 'ad', '1');
INSERT INTO `tb_user` VALUES ('5', '小红2', '1', 'eqw', '1');

Order by与Group by的优化原则与最左匹配原则一致,在排序字段中使用索引可以达到优化的效果;

分析:利用最左前缀法则:中间字段不能断,因此查询用到了name索引,从key_len=75也能看出,adress索引列用在排序过程中,因为Extra字段里没有using filesort; 可是索引的长度并没有用到联合索引的总长度?

例2:使用索引排序需按照降序都降序,升序都升序而且必须遵守最左匹配

EXPLAIN SELECT * from tb_user where `name`='小红'  ORDER BY sex desc,adress desc ; true

EXPLAIN SELECT * from tb_user where `name`='小红'  ORDER BY sex  , adress ;true

EXPLAIN SELECT * from tb_user where `name`='小红'  ORDER BY adress , sex ; false

EXPLAIN SELECT * from tb_user where `name` > '小红'  ORDER BY adress , sex ; false

mysql系列(七)mysql 主从复制和mysql查询优化_第2张图片

Using filesort文件排序原理详解

filesort文件排序方式:

  1. 单路排序:是一次性取出满足条件行的所有字段,然后在sort buffer中进行排序;用trace工具可以看到sort_mode信息里显示< sort_key, additional_fields >或者< sort_key,packed_additional_fields >
  2. 双路排序(又叫回表排序模式):是首先根据相应的条件取出相应的排序字段和可以直接定位行数据的行 ID,然后在 sort buffer 中进行排序,排序完后需要再次取回其它需要的字段;用trace工具可以看到sort_mode信息里显示< sort_key, rowid >

MySQL 通过比较系统变量 max_length_for_sort_data(默认1024字节) 的大小和需要查询的字段总大小来 判断使用哪种排序模式。

  • 如果 max_length_for_sort_data 比查询字段的总长度大,那么使用 单路排序模式;
  • 如果 max_length_for_sort_data 比查询字段的总长度小,那么使用 双路排序模式。

优化总结:

  1. MySQL支持两种方式的排序filesort和index,Using index是指MySQL扫描索引本身完成排序。index效率高,filesort效率低。
  2. order by满足两种情况会使用Using index。
  • 1) order by语句使用索引最左前列。
  • 2) 使用where子句与order by子句条件列组合满足索引最左前列。
  1. 尽量在索引列上完成排序,遵循索引建立(索引创建的顺序)时的最左前缀法则。
  2. 如果order by的条件不在索引列上,就会产生Using filesort。
  3. 能用覆盖索引尽量用覆盖索引
  4. group by与order by很类似,其实质是先排序后分组,遵照索引创建顺序的最左前缀法则。对于group by的优化如果不需要排序的可以加上order by null禁止排序。注意,where高于having,能写在where中的限定条件就不要去having限定了。

6.2 优化COUNT()查询

 

  1. 优化关联查询
  2. 优化GROUP BY与Order by
  3. 优化LIMIT分页(延迟加载)
  4. 优化UNION查询

 

7.mysql服务器配置

配置文件的位置:

windows系统一般在MySQL安装目录下的data目录

Linux系统一般在/etc/my.cnf或/etc/mysql/my.cnf

#查看MySQL加载配置文件的顺序,注意:后面的配置项会覆盖前面的配置项

  1. mysqld --verbose --help|grep -A 1 'Default options'
  2. max_connections:允许客户端并发连接的最大数量,默认值151,一般设置为500-2000 (和服务器配置有关)
  3. max_connect_errors:如果客户端尝试连接的错误数量超过这个参数,则服务器不再接受新的客户端连接
  4. back_log:MySQL服务器连接请求队列所能处理的最大连接请求数(默认80)
  5. open_files_limit:操作系统允许MySQL服务打开的文件数量
  6. table_open_cache:所有线程能打开的表的数量
  7. thread_cache_size:MySQL服务缓存以重用的线程数

你可能感兴趣的:(mysql)