美文网首页
MySQL总结

MySQL总结

作者: 沐熙一叶_Leaf | 来源:发表于2021-04-12 10:03 被阅读0次

    1、总结mysql常见的存储引擎以及特点。

    1、1 MyISAM存储引擎

    • 不支持事务

    • 表级锁定

    • 读写相互阻塞,写入不能读,读时不能写

    • 只缓存索引

    • 不支持外键约束

    • 不支持聚簇索引

    • 读取数据较快,占用资源较少

    • 不支持MVCC(多版本并发控制机制)高并发

    • 崩溃恢复性较差

    • MySQL5.5.5前默认的数据库引擎

    MyISAM存储引擎适用场景
    • 只读(或者写较少)
    • 表较小(可以接受长时间进行修复操作)
    MyISAM引擎文件
    • tbl_name.frm 表格式定义

    • tbl_name.MYD 数据文件

    • tbl_name.MYI 索引文件

    1、2 InnoDB引擎

    InnoDB引擎特点
    • 行级锁
    • 支持事务,适合处理大量短期事务
    • 读写阻塞与事务隔离级别相关
    • 可缓存数据和索引
    • 支持聚簇索引
    • 崩溃恢复性更好
    • 支持MVCC高并发
    • 从MySQL5.5后支持全文索引
    • 从MySQL5.5.5开始为默认的数据库引擎
    InnoDB数据库文件
    • 所有InnoDB表的数据和索引放置于同一个表空间中
    数据文件:ibdata1, ibdata2,存放在datadir定义的目录下
    表格式定义:tb_name.frm,存放在datadir定义的每个数据库对应的目录下
    
    • 每个表单独使用一个表空间存储表的数据和索引 两类文件放在对应每个数据库独立目录中
    数据文件(存储数据和索引):tb_name.ibd
    表格式定义:tb_name.frm  
    

    1、3 其它存储引擎

    • Performance_Schema:Performance_Schema数据库使用
    • Memory :将所有数据存储在RAM中,以便在需要快速查找参考和其他类似数据的环境中进行快速访问。适用存放临时数据。引擎以前被称为HEAP引擎
    • MRG_MyISAM:使MySQL DBA或开发人员能够对一系列相同的MyISAM表进行逻辑分组,并将它们作为一个对象引用。适用于VLDB(Very Large Data Base)环境,如数据仓库
    • Archive :为存储和检索大量很少参考的存档或安全审核信息,只支持SELECT和INSERT操作;支持行级锁和专用缓存区
    • Federated联合:用于访问其它远程MySQL服务器一个代理,它通过创建一个到远程MySQL服务器的客户端连接,并将查询传输到远程服务器执行,而后完成数据存取,提供链接单独MySQL服务器的能力,以便从多个物理服务器创建一个逻辑数据库。非常适合分布式或数据集市环境
    • BDB:可替代InnoDB的事务引擎,支持COMMIT、ROLLBACK和其他事务特性
    • Cluster/NDB:MySQL的簇式数据库引擎,尤其适合于具有高性能查找要求的应用程序,这类查找需求还要求具有最高的正常工作时间和可用性
    • CSV:CSV存储引擎使用逗号分隔值格式将数据存储在文本文件中。可以使用CSV引擎以CSV格式导入和导出其他软件和应用程序之间的数据交换
    • BLACKHOLE :黑洞存储引擎接受但不存储数据,检索总是返回一个空集。该功能可用于分布式数据库设计,数据自动复制,但不是本地存储
    • example:“stub”引擎,它什么都不做。可以使用此引擎创建表,但不能将数据存储在其中或从中检索。目的是作为例子来说明如何开始编写新的存储引擎

    2、总结MySQL查询缓存优化总结。

    2、1查询缓存原理

    缓存SELECT操作或预处理查询的结果集和SQL语句,当有新的SELECT语句或预处理查询语句请求,先去查询缓存,判断是否存在可用的记录集,判断标准:与缓存的SQL语句,是否完全一样,区分大小写

    优缺点
    • 不需要对SQL语句做任何解析和执行,当然语法解析必须通过在先,直接从Query Cache中获得查询结果,提高查询性能
    • 查询缓存的判断规则,不够智能,也即提高了查询缓存的使用门槛,降低效率
    • 查询缓存的使用,会增加检查和清理Query Cache中记录集的开销
    哪些查询可能不会被缓存
    • 查询语句中加了SQL_NO_CACHE参数
    • 查询语句中含有获得值的函数,包含:自定义函数,如:NOW() ,CURDATE()、GET_LOCK()、RAND()、CONVERT_TZ()等
    • 对系统数据库的查询:mysql、information_schema 查询语句中使用SESSION级别变量或存储过
      程中的局部变量
    • 查询语句中使用了LOCK IN SHARE MODE、FOR UPDATE的语句,查询语句中类似SELECT …INTO 导出数据的语句
    • 对临时表的查询操作
    • 存在警告信息的查询语句
    • 不涉及任何表或视图的查询语句
    • 某用户只有列级别权限的查询语句
    • 事务隔离级别为Serializable时,所有查询语句都不能缓存

    2、2查询缓存相关的服务器变量

    • query_cache_min_res_unit:查询缓存中内存块的最小分配单位,默认4k,较小值会减少浪费,
      但会导致更频繁的内存分配操作,较大值会带来浪费,会导致碎片过多,内存不足
    • query_cache_limit:单个查询结果能缓存的最大值,单位字节,默认为1M,对于查询结果过大而
      无法缓存的语句,建议使用SQL_NO_CACHE
    • query_cache_size:查询缓存总共可用的内存空间;单位字节,必须是1024的整数倍,最小值
      40KB,低于此值有警报
    • query_cache_wlock_invalidate:如果某表被其它的会话锁定,是否仍然可以从查询缓存中返回结
      果,默认值为OFF,表示可以在表被其它会话锁定的场景中继续从缓存返回数据;ON则表示不允
    • query_cache_type:是否开启缓存功能,取值为ON, OFF, DEMAND

    2、3 SELECT语句的缓存控制

    • SQL_CACHE:显式指定存储查询结果于缓存之中
    • SQL_NO_CACHE:显式查询结果不予缓存
    • query_cache_type参数变量
    • query_cache_type的值为OFF或0时,查询缓存功能关闭
    • query_cache_type的值为ON或1时,查询缓存功能打开,SELECT的结果符合缓存条件即会缓存,
      否则,不予缓存,显式指定SQL_NO_CACHE,不予缓存,此为默认值
    • query_cache_type的值为DEMAND或2时,查询缓存功能按需进行,显式指定SQL_CACHE的SELECT语句才会缓存;其它均不予缓存

    2、4 查询缓存相关的状态变量

    SHOW GLOBAL STATUS LIKE 'Qcache%';
    
    • Qcache_free_blocks:处于空闲状态 Query Cache中内存 Block 数
    • Qcache_total_blocks:Query Cache 中总Block ,当Qcache_free_blocks相对此值较大时,可能用内存碎片,执行FLUSH QUERY CACHE清理碎片
    • Qcache_free_memory:处于空闲状态的 Query Cache 内存总量
    • Qcache_hits:Query Cache 命中次数
    • Qcache_inserts:向 Query Cache 中插入新的 Query Cache 的次数,即没有命中的次数
    • Qcache_lowmem_prunes:记录因为内存不足而被移除出查询缓存的查询数
    • Qcache_not_cached:没有被 Cache 的 SQL 数,包括无法被 Cache 的 SQL 以及由于query_cache_type 设置的不会被 Cache 的 SQL语句
    • Qcache_queries_in_cache:在 Query Cache 中的 SQL 数量

    2、5 命中率和内存使用率估算

    • 查询缓存中内存块的最小分配单位query_cache_min_res_unit :

      (query_cache_size - Qcache_free_memory) / Qcache_queries_in_cache
      
    • 查询缓存命中率 :

      Qcache_hits / ( Qcache_hits + Qcache_inserts ) * 100%
      
    • 查询缓存内存使用率:

      (query_cache_size – qcache_free_memory) / query_cache_size * 100%  
      

    注意:

    MySQL8.0 取消查询缓存的功能

    尽管MySQL Query Cache旨在提高性能,但它存在严重的可伸缩性问题,并且很容易成为严重的瓶颈。
    自MySQL 5.6(2013)以来,默认情况下已禁用查询缓存,其不能与多核计算机上在高吞吐量工作负载情况下进行扩展。

    另外有时因为查询缓存往往弊大于利。比如:查询缓存的失效非常频繁,只要有对一个表的更新,这个表上的所有的查询缓存都会被清空。因此很可能你费劲地把结果存起来,还没使用呢,就被一个更新全清空了。对于更新压力大的数据库来说,查询缓存的命中率会非常低。除非你的业务有一张静态表,很长时间更新一次,比如系统配置表,那么这张表的查询才适合做查询缓存。

    目前大多数应用都把缓存做到了应用逻辑层,比如:使用redis或者memcache

    3、MySQL日志各类总结

    MySQL 支持丰富的日志类型,如下:

    • 事务日志:transaction log

    • 事务日志的写入类型为“追加”,因此其操作为“顺序IO”;通常也被称为:预写式日志 write ahead logging

      事务日志文件:ib_logfile0, ib_logfile1

    • 错误日志:error log

    • 通用日志:general log

    • 慢查询日志:slow query log

    • 二进制日志:binary log

    • 中继日志:reley log,在主从复制架构中,从服务器用于保存从主服务器的二进制日志中读取的事件

    3、1 事务日志

    事务日志:transaction log
    事务型存储引擎自行管理和使用,建议和数据文件分开存放,redo log和undo log

    Innodb事务日志相关配置:

    show variables like '%innodb_log%';
    
    innodb_log_file_size 50331648   每个日志文件大小
    innodb_log_files_in_group 2     日志组成员个数
    innodb_log_group_home_dir ./    事务文件路径
    innodb_flush_log_at_trx_commit  默认为1
    

    事务日志性能优化

    innodb_flush_log_at_trx_commit=0|1|2
    
    1 此为默认值,日志缓冲区将写入日志文件,并在每次事务后执行刷新到磁盘。 这是完全遵守ACID特性
    0 提交时没有写磁盘的操作; 而是每秒执行一次将日志缓冲区的提交的事务写入刷新到磁盘。 这样可提供更好的性能,但服务器崩溃可能丢失最后一秒的事务
    2 每次提交后都会写入OS的缓冲区,但每秒才会进行一次刷新到磁盘文件中。 性能比0略差一些,但操作系统或停电可能导致最后一秒的交易丢失
    

    高并发业务行业最佳实践,是使用第三种折衷配置(=2):

    1.配置为2和配置为0,性能差异并不大,因为将数据从Log Buffer拷贝到OS cache,虽然跨越用户态与内核态,但毕竟只是内存的数据拷贝,速度很快
    2.配置为2和配置为0,安全性差异巨大,操作系统崩溃的概率相比MySQL应用程序崩溃的概率,小很多,设置为2,只要操作系统不奔溃,也绝对不会丢数据
    

    说明:

    设置为1,同时sync_binlog = 1表示最高级别的容错
    innodb_use_global_flush_log_at_trx_commit=0 时,将不能用SET语句重置此变量( MariaDB 10.2.6
    后废弃)

    3、2 错误日志

    错误日志

    • mysqld启动和关闭过程中输出的事件信息
    • mysqld运行中产生的错误信息
    • event scheduler运行一个event时产生的日志信息
    • 在主从复制架构中的从服务器上启动从服务器线程时产生的信息

    错误文件路径

    SHOW GLOBAL VARIABLES LIKE 'log_error'
    

    记录哪些警告信息至错误日志文件

    #CentOS7 mariadb 5.5 默认值为1
    #CentOS8 mariadb 10.3 默认值为2
    log_warnings=0|1|2|3...
    

    3、3 通用日志

    • 通用日志:记录对数据库的通用操作,包括:错误的SQL语句
    • 通用日志可以保存在:file(默认值)或 table(mysql.general_log表)

    通用日志相关设置

    general_log=ON|OFF
    general_log_file=HOSTNAME.log
    log_output=TABLE|FILE|NONE
    

    3、4慢查询日志

    慢查询日志:记录执行查询时长超出指定时长的操作

    慢查询相关变量

    slow_query_log=ON|OFF   #开启或关闭慢查询,支持全局和会话,只有全局设置才会生成慢查询文件
    long_query_time=N       #慢查询的阀值,单位秒
    slow_query_log_file=HOSTNAME-slow.log   #慢查询日志文件
    log_slow_filter = admin,filesort,filesort_on_disk,full_join,full_scan,
    query_cache,query_cache_miss,tmp_table,tmp_table_on_disk
    #上述查询类型且查询时长超过long_query_time,则记录日志
    log_queries_not_using_indexes=ON    #不使用索引或使用全索引扫描,不论是否达到慢查询阀值的语
    句是否记录日志,默认OFF,即不记录
    log_slow_rate_limit = 1     #多少次查询才记录,mariadb特有
    log_slow_verbosity= Query_plan,explain  #记录内容
    log_slow_queries = OFF      #同slow_query_log,MariaDB 10.0/MySQL 5.6.1 版后已删除
    

    2、5 二进制日志(备份)

    • 记录导致数据改变或潜在导致数据改变的SQL语句
    • 记录已提交的日志
    • 不依赖于存储引擎类型

    功能:通过“重放”日志文件中的事件来生成数据副本
    注意:建议二进制日志和数据文件分开存放

    二进制日志记录三种格式

    • 基于“语句”记录:statement,记录语句,默认模式( MariaDB 10.2.3 版本以下 ),日志量较少
    • 基于“行”记录:row,记录数据,日志量较大,更加安全,建议使用的格式
    • 混合模式:mixed, 让系统自行判定该基于哪种方式进行,默认模式( MariaDB 10.2.4及版本以上)

    二进制日志文件的构成

    有两类文件
    1.日志文件:mysql|mariadb-bin.文件名后缀,二进制格式,如: mariadb-bin.000001
    2.索引文件:mysql|mariadb-bin.index,文本格式
    

    二进制日志相关的服务器变量:

    sql_log_bin=ON|OFF:#是否记录二进制日志,默认ON,支持动态修改,系统变量,而非服务器选项
    log_bin=/PATH/BIN_LOG_FILE:#指定文件位置;默认OFF,表示不启用二进制日志功能,上述两项都开
    启才可以
    binlog_format=STATEMENT|ROW|MIXED:#二进制日志记录的格式,默认STATEMENT
    max_binlog_size=1073741824:#单个二进制日志文件的最大体积,到达最大值会自动滚动,默认为1G
    #说明:文件达到上限时的大小未必为指定的精确值
    binlog_cache_size=4m #此变量确定在每次事务中保存二进制日志更改记录的缓存的大小(每次连接)
    max_binlog_cache_size=512m #限制用于缓存多事务查询的字节大小。
    sync_binlog=1|0:#设定是否启动二进制日志即时同步磁盘功能,默认0,由操作系统负责同步日志到磁盘
    expire_logs_days=N:#二进制日志可以自动删除的天数。 默认为0,即不自动删除
    

    二进制日志相关配置

    查看mariadb自行管理使用中的二进制日志文件列表,及大小

    SHOW {BINARY | MASTER} LOGS
    

    查看使用中的二进制日志文件

    SHOW MASTER STATUS
    

    在线查看二进制文件中的指定内容

    SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]
    

    mysqlbinlog:二进制日志的客户端命令工具,支持离线查看二进制日志

    命令格式:

    mysqlbinlog [OPTIONS] log_file…
            --start-position=   # 指定开始位置
            --stop-position=    #
            --start-datetime=   #时间格式:YYYY-MM-DD hh:mm:ss
            --stop-datetime=
            --base64-output[=name]
            -v -vvv
    

    二进制日志事件的格式:

    # at 328
    #151105 16:31:40 server id 1 end_log_pos 431 Query thread_id=1
    exec_time=0 error_code=0
    use `mydb`/*!*/;
    SET TIMESTAMP=1446712300/*!*/;
    CREATE TABLE tb1 (id int, name char(30))
    /*!*/;
    事件发生的日期和时间:151105 16:31:40
    事件发生的服务器标识:server id 1
    事件的结束位置:end_log_pos 431
    事件的类型:Query
    事件发生时所在服务器执行此事件的线程的ID:thread_id=1
    语句的时间戳与将其写入二进制文件中的时间差:exec_time=0
    错误代码:error_code=0
    事件内容:
    GTID:Global Transaction ID,mysql5.6以mariadb10以上版本专属属性:GTID
    

    清除指定二进制日志

    PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr }
    删除所有二进制日志,index文件重新记数
    

    删除所有二进制日志,index文件重新记数

    RESET MASTER [TO #]; #删除所有二进制日志文件,并重新生成日志文件,文件名从#开始记数,默认从
    1开始,一般是master主机第一次启动时执行,MariaDB 10.1.6开始支持TO #
    

    切换日志文件

    FLUSH LOGS;
    

    相关文章

      网友评论

          本文标题:MySQL总结

          本文链接:https://www.haomeiwen.com/subject/ymezkltx.html