MySQL 高级(4): 相关工具的使用与主从复制

相关工具

慢查询

概念

  • MySQL 的慢查询日志是 MySQL 提供的一种日志记录,它用来记录在 MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。

开启慢查询

  • 默认情况下,MySQL 数据库没有开启慢查询日志,需要我们手动来设置这个参数。

  • 当然,如果不是调优需要的话,一般不建议启动该参数, 因为开启慢查询日志会或多或少带来一定的性能影响。慢查询日志支持将日志记录写入文件。

  • 开启设置如下:

    QL语句 描述 备注
    HOW VARIABLES LIKE ‘%slow_query_log%’; 查看慢查询日志是否开启 默认情况下 slow_query_log 的值为 OFF,表示慢查询日志是禁用的
    et global slow_query_log=1; 开启慢查询日志
    HOW VARIABLES LIKE ‘long_query_time%’; 查看慢查询设定阈值 单位秒
    et long_query_time=1 设定慢查询阈值 单位秒
  • 永久生效需要修改配置文件my.cnf 中[mysqld]下配置

    [mysqld]
    slow_query_log=1
    slow_query_log_file=/var/lib/mysql/atguigu-slow.log
    long_query_time=3
    log_output=FILE
    

mysqldumpslow

mysqldumpslow 为 日志分析的工具包,主要存在以下这些功能(可以通过 root@cocoon ~]# mysqldumpslow --help 查看):
参数| 描述

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

实例

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

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

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

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

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

SHOW PROCESSLIST

SHOW PROCESSLIST 可以用来查询 mysql 进程列表。在杀掉故障进程的过程中可以使用。
在这里插入图片描述

主从复制

什么是主从复制?

主从复制 ,是用来建立一个和主数据库完全一样的数据库环境(从数据库)的一种架构和算法,主数据库一般是准实时的业务数据库。

主从复制的作用?

  • 1、架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,物理服务器增加,负荷增加。异地备份

  • 2、读写分离,使数据库能支撑更大的并发。主从只负责各自的写和读,极大程度的缓解X锁和S锁争用。在报表中尤其重要。由于部分报表sql语句非常的慢,导致锁表,影响前台服务。如果前台使用 master,报表使用 slave,那么报表 sql 将不会造成前台锁,保证了前台速度。负载均衡
    在这里插入图片描述

  • 3、做数据的热备,作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。实现同步,增加了数据系统的可用性

在这里插入图片描述

主从复制的原理:

  • 1、 主库db的更新事件(update、insert、delete)被写到binlog,binlog为一个二进制文件,记录了所有sql语句。
  • 2.、从库发起连接,连接到主库
  • 3、 此时主库创建一个binlog dump thread线程(binlog镜像输出线程),把binlog的内容发送到从库。
  • 4.、从库启动之后(binlog dump thread线程的复制开始时),创建一个I/O线程,读取主库传过来的binlog内容并写入到relay log.
  • 5.、还会创建一个SQL线程,从relay log里面读取内容,从Exec_Master_Log_Pos位置开始执行读取到的更新事件,将更新内容写入到slave的db.

主从复制的方式

  • 同步复制
    所谓的同步复制,意思是master的变化,必须等待slave-1,slave-2,…,slave-n完成后才能返回。
    这样,显然不可取,也不是MYSQL复制的默认设置。比如,在WEB前端页面上,用户增加了条记录,需要等待很长时间。

  • 异步复制
    如同AJAX请求一样。master只需要完成自己的数据库操作即可。至于slaves是否收到二进制日志,是否完成操作,不用关心。MYSQL的默认设置。

  • 半同步复制
    master只保证slaves中的一个操作成功,就返回,其他slave不管。
    这个功能,是由google为MYSQL引入的。

主要参数:

1、innodb_flush_log_at_trx_commit

innodb_flush_log_at_trx_commit:是 InnoDB 引擎特有的,ib_logfile的刷新方式(ib_logfile:记录的是redo log和undo log的信息)取值:0/1/2

  • innodb_flush_log_at_trx_commit=0: 表示每隔一秒把log buffer刷到文件系统中(os buffer)去,并且调用文件系统的“flush”操作将缓存刷新到磁盘上去。也就是说一秒之前的日志都保存在日志缓冲区,也就是内存上,如果机器宕掉,可能丢失1秒的事务数据。
  • innodb_flush_log_at_trx_commit=1:表示在每次事务提交的时候,都把log buffer刷到文件系统中(os buffer)去,并且调用文件系统的“flush”操作将缓存刷新到磁盘上去。这样的话,数据库对IO的要求就非常高了,如果底层的硬件提供的IOPS比较差,那么MySQL数据库的并发很快就会由于硬件IO的问题而无法提升。
  • innodb_flush_log_at_trx_commit=2 :表示在每次事务提交的时候会把log buffer刷到文件系统中去,但并不会立即刷写到磁盘。 如果只是MySQL数据库挂掉了,由于文件系统没有问题,那么对应的事务数据并没有丢失。只有在数据库所在的主机操作系统损坏或者突然掉电的情况下,数据库的事务数据可能丢失1秒之类的事务数据。这样的好处,减少了事务数据丢失的概率,而对底层硬件的IO要求也没有那么高(log buffer写到文件系统中,一般只是从log buffer的内存转移的文件系统的内存缓存中,对底层IO没有压力)。

2、sync_binlog

sync_binlog:是MySQL 的二进制日志(binary log)同步到磁盘的频率。取值:0-N

  • sync_binlog=0,当事务提交之后,MySQL不做fsync之类的磁盘同步指令刷新binlog_cache中的信息到磁盘,而让Filesystem自行决定什么时候来做同步,或者cache满了之后才同步到磁盘。
  • sync_binlog=n,当每进行n次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘。

数据库的读的延迟问题了解吗?如何解决?

答: 简单说就是主库在高并发下,产生的 DDL 语句超过了一个从库的一个SQL线程所能够承受的范围,进而产生了网络延迟

详细的说:

  • 谈到 MySQL 数据库的同步延迟,就必须要从主从复制开始说起。主从复制的主要操作 blablabla
  • 而主从复制中主要包括的三个线程都是单线程执行。binglog镜像输出线程主要是对所有的DDL进行顺序写,所以效率很高。从库中的 I/O 线程主要是从主库中取日志,效率也比较高。但是从库中的 SQL 线程就是在从库中实施这些SQL语句了。由于该线程也为单线程,因此可能由于锁的争用线程等待等问题,消耗大量的时间成本。
  • 为什么主库没有造成时间延迟的原因是:主库的运行线程时并发的,即多线程的

解决方案:

  • 解决方法一:最简单的减少从库的同步延时的方案就是在架构上做优化,尽量让主库的DDL快速执行。还有就是主库是写,对数据安全性较高,比如 sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之类的设置,而slave则不需要这么高的数据安全,完全可以将 sync_binlog 设置为 0 或者关闭 binlog,innodb_flushlog也可以设置为0来提高sql的执行效率。另外就是使用比主库更好的硬件设备作为slave。

  • 解决方法二:数据放入缓存中,更新数据库后,在预期可能马上用到的情况下,主动刷新缓存

  • 解决办法三:对于比较重要且必须实时的数据,比如用户刚换密码(密码写入 Master),然后用新密码登录(从 Slaves 读取密码),会造成密码不一致,导致用户短时间内登录出错。所以在这种需要读取实时数据的时候最好从 Master 直接读取,避免 Slaves 数据滞后现象发生。

读写分离的实现方法:

为了减轻数据库的压力,一般会进行数据库的读写分离,实现

  • 方法一是通过分析sql语句是insert/select/update/delete 中的哪一种,从而对应选择主从。
  • 二是通过拦截方法名称的方式来决定主从的,如:save*()、insert*() 形式的方法使用master库,select()开头的使用slave库。

猜你喜欢

转载自blog.csdn.net/Mr_tianyanxiaobai/article/details/119914349