MySQL优化-MySQL体系结构

MySQL优化-MySQL体系结构

三层体系结构:
连接层
SQL层
存储层

关于timeout
    通过jdbc等程序连接的是非交互会话。
    通过mysql cli客户端连接的是交互会话。

    wait_timeout,关闭非交互连接(程序端)之前等待的秒数。默认8h。
    interactive_timeout,关闭交互式连接(客户端)前等待的秒数。默认8h。

本节小结:
    5.7开始,支持密码过期机制。
    8.0开始,支持更多密码安全机制,更安全的MySQL 8.0之全新密码策略。
    一些LB应用会疯狂探测数据库,可能会造成被blocked。
    调整合理的timeout阈值,减少连接数浪费。

配置文件my.cnf
[client]是所有客户端工具全局选项(mysql/mysqladmin/mysqldump/mysqlshow等)
[mysql] 是mysql客户端的相关选项、账号、密码、socket、字符集、auth-rehash等。

.frm 文件可以用mysqlfrm工具解析。
.ibt user session innodb temp tablespace.
.ibu 用户自定义的undo表空间文件。

支持DDL原子性,都成功或都失败。
I_S查询性能提升(以往总是需要先访问.frm文件),并增加cache机制。
information_schema_stats_expiry控制元数据缓存失效时长,设置为0不缓存,或者analyze table也会更新缓存。
设置innodb_read_only后,就无法创建任何新表。
手动mkdir newDB,无法被自动识别。
DDL过程涉及InnoDB引擎事务系统,会相对略慢些。

本节小结:
    8.0之后,元数据全部存储在InnoDB里。
    不要再任性手动创建一个目录或者删除文件,可能造成元数据损坏。
    使用独立undo表空间,以及独立用户表空间。

并行复制writeset机制
5.7的并行复制效率,取决于事务在主库上的并发度。如果主库上并发度不高,或者有大事务,则从库延迟依然比较严重。
8.0的writeset模式完美解决了这个难题:即便在主库是串行提交,但只要事务间不冲突,在从库依然可以并行回放。
新增选项binlog_transaction_dependency_tracking。
    commit_ordere(默认),基于锁的并发策略,使用5.7的group commit机制决定事务依赖。
    writeset(建议)基于主键的并发策略,可以并发的执行同一个session内的事务(只要不冲突),具有最好的性能。
    writeset_session,基于主键的并发策略,不可以并发执行同一个session内的事务。

MySQL 8.0新特性介绍
    1.消除了buffer pool mutex(Percona的贡献)。
    2.数据字典全部采用InnoDB引擎存储,支持DDL原子性、crash safe,metadata管理更完善(可以利用ibd2sdi工具提取metadata)。
        # ibd2sdi t1.ibd -d t1.sdi
    3.快速在线加新列(腾讯互娱DBA团队贡献)
    4.并行redo log,并提升redo log的I/O性能,可在线调整redo log buffer。
    5.新增倒叙索引,不可见索引。
    6.优化器增强,增强CBO特性。
    7.支持会话级别SET_VAR动态调整部分参数。
    8.重构SQL分析器(SQLParser)。
    9.行锁增加skip locked和nowait特性选项。
    10.新增事务CATS特性,大大提升事务性能(Michigan大学贡献)。
    11.在线修改undo log数量。
    12.直方图。
    13.认证插件由sha256_password改成caching_sha2_password。
    14.新增角色role功能,将权限打包分组再二次授权。
    15.自增列持久化。
    16.增强json性能、功能。
    17.新增智能选项innodb_dedicated_server。
    18.InnoDB memcached插件支持mget操作。
    19.增加redo/undo log加密。
    20.增加resource group功能。
    21.新增更多数据字典。
    22.默认字符集改成utf8mb4。
    23.通用表达式CTE。
    24.窗口函数。
    25.set persist。
    26.restart功能。
    27.取消QC。

8.0.14后新特性:
    双密码机制
    binlog加密
    log_slow_extra
    admin_port
    innodb_buffer_pool_in_core_file
    MySQL InnoDB Cluster支持IPv6

虚拟列
5.7开始支持json、虚拟列,看起来是为8.0的函数索引,表达式索引做准备。
此外,8.0开始支持json的多值索引模式。

临时表/临时文件
    用户创建的显式临时表,create temporary table。
    内部临时表,SQL执行时优化器创建的隐式临时表。
    临时表超过内存限制后,就会转成磁盘临时表。
相关选项
    tmp_table_size / max_heap_table_size
    temptable_max_ram
    internal_tmp_disk_storage_engine
    innodb_temp_tablespace_dir
    innodb_temp_data_file_path

临时文件
可见临时文件,用完后自行删除。
不可见文件,创建后立即unlink,需要用lsof才能看到,默认存储在tmpdir下。
运行状态下,vim打开log文件后保存,也会生成deleted状态的不可见文件。
binlog中未提交事务太大时,需要binlog disk cache,ML****。
filesort排序时,内存放不下,需要磁盘文件,MY****。
主库执行load data时,从库也会有相应的临时磁盘文件(slave_load_tmpdir)。
执行show create table查看分区表时,也会生成临时文件。
innodb引擎也会创建临时文件,用于存储最新外键&唯一约束错误、死锁信息、innodb状态信息。

DDL过程中生成的临时文件。
online DDL的过程中,有时需要重建原表,同时需要对二级索引排序,会创建ibXXXXXX这样的临时文件。
DDL过程中,还允许DML进行,就需要把这些DML操作记录到online log中。log较少时,就放在内存(innodb_sort_buffer_size)中,较大时就会转成磁盘临时文件,存储在innodb_tmpdir下。
当online log超限(innodb_online_alter_log_max_size)后,DDL失败。
在DDL的最后阶段,要把上面排序完的临时文件和online log全部都应用到一个中间文件中,文件名叫sql-ibX1-X2.ibd中(X1是table id,X2是随机数)。此外,在8.0前还会生成.frm文件,8.0后则不会。

几个优化建议
创建索引,减少额外排序、分组。
适当调大sort_buffer_size、tmp_table_size和max_heap_table_size,temptable_max_ram,减少磁盘表。
减少大事务以避免binlog_cache过大,适当调大binlog_cache_size。
多用短连接,因为连接断开后,一些session级内存(例如binlog cache)会及时释放,减少binlog disk cache机会。
当确定知道SQL会生成大表时,可告知优化器直接生成磁盘表,减少内存=>磁盘的转化开销,select ... sql_big_result ... (sql_small_result)。

本节小结:
建议使用8.0后默认的temptable引擎,性能更好。
尽量不使用临时表。
有用到临时表的会话,记得关闭/重置连接,释放临时表。
尽量不online DDL,若innodb_online_alter_log_max_size不够大会失败。
不要用vi打开正在运行的数据文件、日志文件。

怎么调整内存相关选项,如何尽可能避免发生内存溢出?
内存泄露,memory leak,内存跑到黑洞里,不可用了。
内存溢出,memory overflow, out of memory,申请的内存超过物理内存大小。
MySQL内存结构:
    全局:
        只分配一次。
        全局共享。
    连接/会话:
        针对每个会话/线程分配。
        按需动态分配,查询结束后释放。
        用于处理(缓冲、中转)查询结果。
        每个会话的缓冲区大小都不一样。
        多用短连接,以为连接断开后,一些session级内存会及时释放。

连接/会话层:net/read/join/sort/bulk insert buffer、tmp/heap table,binlog cache
sql层/server层:query cahce、table (def) cache、thread cache、mdl cache
引擎层:innodb buffer、innodb log buffer、key buffer、myisam sort buffer size

mysqld进程消耗内存估算 = global buffers + all thread buffers

全局分配内存global buffer(类似SGA)
= innodb buffer pool
+ innodb log buffer
+ key buffer
+ query cache
+ table cache
+ thread cache

会话/线程级分配内存all thread buffers(类似PGA)
= max_threads * (
    read buffer
  + read rnd buffer
  + sort buffer
  + join buffer
  + tmp table
  + binlog cache
  + histogram ram)

两个容易被设置很大的内存选项
    都是session级
    max_heap_table_size限制memory表最大容量,不管其他执行SQL产生的临时表,若内存不够用,则不允许写入新的数据,memory表也不会转成磁盘表,只会告警超限后拒绝写入。
    tmp_table_size不限制memory表最大容量,如果执行SQL产生临时表超过tmp_table_size或max_heap_table_size,则会产生基于磁盘的临时表。
    这2个选项特别容易分配较大,若有需要,可临时调大,不要修改全局值。

查看buffer pool的组成
[[email protected]:mysql.sock] [(none)]> select page_type as page_type,
    -> sum(data_size)/1024/1024 as Size_in_MB
    -> from information_schema.innodb_buffer_page
    -> group by page_type
    -> order by Size_in_MB desc;
+-------------------+-------------+
| page_type         | Size_in_MB  |
+-------------------+-------------+
| INDEX             | 17.88112068 |
| INODE             |  0.00000000 |
| SYSTEM            |  0.00000000 |
| UNKNOWN           |  0.00000000 |
| FILE_SPACE_HEADER |  0.00000000 |
| UNDO_LOG          |  0.00000000 |
| TRX_SYSTEM        |  0.00000000 |
| IBUF_BITMAP       |  0.00000000 |
| IBUF_INDEX        |  0.00000000 |
+-------------------+-------------+
9 rows in set (0.12 sec)

查看表的数据和索引使用情况
select engine, count(*) as TABLES,
    concat(round(sum(table_rows)/1000000,2),‘M‘) rs,
    concat(round(sum(data_length)/(1024*1024*1024),2),‘G‘) DATA,
    concat(round(sum(index_length)/(1024*1024*1024),2),‘G‘) idx,
    concat(round(sum(data_length+index_length)/(1024*1024*1024),2),‘G‘) total_size,
    round(sum(index_length)/sum(data_length),2) idxfrac
from information_schema.TABLES
where table_schema not in (‘mysql‘, ‘performance_schema‘, ‘information_schema‘, ‘test‘)
group by engine
order by sum(data_length+index_length)
desc limit 10;

[[email protected]:mysql.sock] [(none)]> select engine, count(*) as TABLES,
    ->     concat(round(sum(table_rows)/1000000,2),‘M‘) rs,
    ->     concat(round(sum(data_length)/(1024*1024*1024),2),‘G‘) DATA,
    ->     concat(round(sum(index_length)/(1024*1024*1024),2),‘G‘) idx,
    ->     concat(round(sum(data_length+index_length)/(1024*1024*1024),2),‘G‘) total_size,
    ->     round(sum(index_length)/sum(data_length),2) idxfrac
    -> from information_schema.TABLES
    -> where table_schema not in (‘mysql‘, ‘performance_schema‘, ‘information_schema‘, ‘test‘)
    -> group by engine
    -> order by sum(data_length+index_length)
    -> desc limit 10;
+--------+--------+-------+-------+-------+------------+---------+
| engine | TABLES | rs    | DATA  | idx   | total_size | idxfrac |
+--------+--------+-------+-------+-------+------------+---------+
| InnoDB |     15 | 6.66M | 0.40G | 0.01G | 0.41G      |    0.04 |
| NULL   |    100 | NULL  | NULL  | NULL  | NULL       |    NULL |
+--------+--------+-------+-------+-------+------------+---------+
2 rows in set (0.11 sec)

关于huge page
使用大页是为了提高内存管理效率。
默认内存页4KB,当有大内存时管理效率较低。采用大页(2MB)时,可以减少内存页数量,提高管理效率。
经过测试,启用大页对MySQL OLTP场景的性能提升很小。
此外,启用透明大页可能反而导致MySQL(TokuDB)更容易发生内存泄露、OOM等问题。
查看是否关闭。
    [[email protected] ~]# cat /sys/kernel/mm/transparent_hugepage/enabled
    [always] madvise never
    [[email protected] ~]# cat /sys/kernel/mm/transparent_hugepage/defrag
    [always] madvise never

本节小结:
从5.7起,innodb buffer pool可以在线动态调整,因此不要设置太大,可以在运行过程中按需加大(只要没有ibp wait free就不用太担心)。
几个可能容易被误以为全局分配的内存选项,不要任性设置太高,主要有tmp_table_size/max_heap_table_size、temptable_max_ram。
从8.0起,临时表默认采用temptable方式存储,整体效率更高。
默认的sql_mode可能比较难用,但建议遵循默认规则。
物理表选择默认的InnoDB引擎,临时表选择默认的temptable引擎。

PT工具使用
information_schema
performance_schema
sys

MySQL客户端工具
    mysql cli
    GUI
        mysql workbench
        navicat

执行mysql_upgrade记得加-f
8.0.16之后就没有mysql_upgrade了。

数据安全:
MySQL服务器没有公网IP。
也不能通过映射/NAT等方案让外部可访问。
也不能绑定全部网卡,明确指定IP。
授权时,务必限制IP段、域名、主机名,而不是全局。
权限务必严格控制,不过度放权。
绝对不能使用弱密码,像123456,abc123,abcd.1234这些。
有条件的话,要求定期更换密码(5.7起可以设置密码定期失效)
应用程序端,数据库连接配置信息尽可能加密。
所有用户输入值都要做过滤。
利用prepare做预处理。
利用sql_mode做限制。
定期扫描,发现异常SQL请求。
或者直接利用审计功能发现异常SQL请求。
    sleep超过5秒。
    访问I_S、P_S、mysql库读取元数据。
    有union、union all特征。
    有updatexml、extractvalue、concat_ws、concat、hex、load_file、outfile、sys_exec、UDF等函数。
mysqld进程必须用普通用户运行,且该用户没有登入shell。
datadir目录仅mysqld进程属主可读写,设置为0700模式。
禁用load_file,必要的话设置可信的source_file_priv。
设置socket文件仅允许mysqld属主访问,其余用户均不可使用(甚至关闭)。
必要时开启审计功能。
禁用old_password选项,如果有可能则采用最新的caching_sha2_password机制。

原文地址:https://www.cnblogs.com/zhouwanchun/p/12669225.html

时间: 2024-11-05 14:54:50

MySQL优化-MySQL体系结构的相关文章

mysql优化 - mysql 的 hint

FORCE INDEX 强制索引 只使用建立在field1上的索引,而不使用其它字段上的索引. SELECT * FROM table1 FORCE INDEX (field1) IGNORE INDEX 忽略索引 table1 表中field1和field2上的索引不被使用 SELECT * FROM table1 IGNORE INDEX (field1, field2) SQL_NO_CACHE 不对结果集进行缓存,关闭查询缓冲 有一些SQL语句需要实时地查询数据,或者并不经常使用(可能一

mysql优化 mysql explain

一篇文章: 使用use index优化sql查询 先看一下arena_match_index的表结构,大家注意表的索引结构CREATE TABLE `arena_match_index` (  `tid` int(10) unsigned NOT NULL DEFAULT '0',  `mid` int(10) unsigned NOT NULL DEFAULT '0',  `group` int(10) unsigned NOT NULL DEFAULT '0',  `round` tinyi

mysql优化-mysql最大连接数

########################### 修改mysql最大连接数 ############################### MYSQL数据库安装完成后,默认最大连接数是100, 一般生产环境的论坛或网站是远远不够的,以下提供两种修改MYSQL最大连接数的方法 ---------------------- 方法1:在线修改mysql最大连接数 --------------------------- 特点:对于mysql在使用中无法停机重启的情况,可以在mysql运行情况下修改

优化MySQL,还是使用缓存?读一篇文章有感

今天我想对一个Greenfield项目上可以采用的各种性能优化策略作个对比.换言之,该项目没有之前决策强加给它的各种约束限制,也还没有被优化过. 具体来说,我想比较的两种优化策略是优化MySQL和缓存.提前指出,这些优化是正交的,唯一让你选择其中一者而不是另一者的原因是他们都耗费了资源,即开发时间. 优化MySQL 优化MySQL时,一般会先查看发送给mysql的查询语句,然后运行explain命令.稍加审查后很常见的做法是增加索引或者对模式做一些调整. 优点 1.一个经过优化的查询对于所有使用

带你认识 MySQL 之 MySQL 体系结构

序 最近一直在忙项目,各种加班加点,项目上线,渐渐的没有了学习的时间.这不,刚这几天才能抽出点时间,忙里偷闲,正在看一本数据库的书籍,相信很多小伙伴们也都看过 - - <MySQL 技术内幕:InnoDB 存储引擎>.这本书很详细的讲述了 MySQL 的设计思想,体系结构,存储引擎,索引,事务,以及对性能的调优等.当然,现在我也是刚刚看了一部分,至于现在写这篇文章,主要是为了记录一下我的学习历程,并且和大家分享一些新的东西. 背景 至于背景嘛,这里就不多说了,如果感兴趣的话,还是推荐大家看一看

MySQL配置文件mysql.ini参数详解、MySQL性能优化

MySQL配置文件mysql.ini参数详解.MySQL性能优化 my.ini(Linux系统下是my.cnf),当mysql服务器启动时它会读取这个文件,设置相关的运行环境参数. my.ini分为两块:Client Section和Server Section.   Client Section用来配置MySQL客户端参数.   要查看配置参数可以用下面的命令: show variables like '%innodb%'; # 查看innodb相关配置参数 show status like

Mysql优化(转)

Mysql优化主要通过执行计划,索引,sql语句,调整mysql内部配置 (http://blog.chinaunix.net/uid-11640640-id-3426908.html) 一.优化概述 二.查询与索引优化分析 1性能瓶颈定位 Show命令 慢查询日志 explain分析查询 profiling分析查询 2索引及查询优化 三.配置优化 1)      max_connections 2)      back_log 3)      interactive_timeout 4)  

MySQL优化—工欲善其事,必先利其器之EXPLAIN

转自:http://www.cnblogs.com/magialmoon/archive/2013/11/23/3439042.html mysql官方手册关于explain命名的说明文档:https://dev.mysql.com/doc/refman/5.7/en/explain-output.html#explain_select_type 最近慢慢接触MySQL,了解如何优化它也迫在眉睫了,话说工欲善其事,必先利其器.最近我就打算了解下几个优化MySQL中经常用到的工具.今天就简单介绍下

MySQL优化概述

MySQL优化概述 设计: 存储引擎,字段类型,范式 功能: 索引,缓存,分区. 架构: 主从复制,读写分离,负载均衡. 合理SQL: 测试,经验. 存储引擎 Create table tableName () engine=myisam|innodb; 一种用来存储MySQL中对象(记录和索引)的一种特定的结构(文件结构) 存储引擎,处于MySQL服务器的最底层,直接存储数据.导致上层的操作,依赖于存储引擎的选择. Tip:存储引擎就是特定的数据存储格式(方案) Show engines 查看