# mysql-study **Repository Path**: wlyfree/mysql-study ## Basic Information - **Project Name**: mysql-study - **Description**: MYSQL学习笔记,架构图、查询路程、索引机制、事务等 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2019-02-19 - **Last Updated**: 2022-02-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # **MYSQL** **注意:部分内容只是用大白话简写了关键点,比如各种数据结构的优缺点,需要自行查阅** ## 架构图 ![](mysql结构.png) Client Connections:接入方,支持的协议比较多 Services & utilities:系统管理工具,备份、分区、集群管理等 Connection Pool:连接池,负责连接处理、权限认证、安全 SQL Interface:SQL接口,DML、DDL语句,存储过程、触发器、视图等,接收SQL指令,返回查询结果 Parser:SQL解析器,由lex和yacc实现 Optimizer:SQL优化器,负责对SQL进行优化 Caches:高速缓存 Indexes:可插拔式的存储引擎,由各种存储引擎进行各自索引的实现,直接与文件打交道 File System:文件系统,包含各种Binary log、error log、slow log、redo、undo、数据和存储等 ## 查询流程 ![](mysql运行.jpg) #### 1.客户端和服务端通信(mysql是半双工通信) ```mysql -- 查看当前占用的连接,限制100条,无SUPER权限账号只能看到自己占用的连接,SUPER权限账号能看到所有连接 show processlist; -- 查看全部连接 show full processlist; -- 可以通过kill ${id}的方式杀掉连接 ``` #### 2.如果开启了缓存,先查询缓存 **缓存相关参数** ```mysql -- mysql是否开启缓存 show variables like 'query_cache_type'; -- 缓冲区大小 show variables like 'query_cache_size'; -- 单个查询能使用的缓冲区大小 show variables like 'query_cache_limit'; -- 缓存使用情况 show status like 'Qcache%'; ``` #### 3.查询优化处理 解析SQL阶段,通过lex词法分析、yacc语法分析将SQL语句解析为树 预处理阶段,检查SQL的合法性,如表或者列是否存储、权限认证等 查询优化器阶段,找到最优的执行计划(Explain) **执行计划** | 属性 | 解释 | | ------------- | ------------------------------------------------------------ | | id | 序列号,标识执行顺序 | | select_type | 查询类型,区分普通查询、联合查询、子查询等 | | table | 查询涉及到的表 | | type | SQL优化指标,由好到坏:system>const>eq_ref>ref>range>index>all | | possible_keys | 查询过程可能用到的索引 | | key | 实际使用的索引,NULL代表未使用索引 | | rows | 根据表统计信息和索引的使用情况,大致估计找到记录所需要读取的行数 | | filtered | 返回结果的行占读取行(rows)的百分比,越大越好 | | Extra | 额外信息,排序、临时表、覆盖索引、where条件、索引查询优化等 | #### 4.查询存储引擎 调用插件式的存储引擎的原子API的功能进行执行计划的执行 #### 5.返回客户端 1.需要做缓存的,就做缓存处理 2.增量返回数据(有第一条数据的时候就开始返回了,用户体验比较好) ### 数据结构 #### 二叉查找树 可能存在线性问题 #### 平衡二叉树 只分两叉,树的层级还是比较高 #### B-Tree:多路平衡树 节点存储关键字、子节点引用、数据,相对平衡二叉树更矮胖一些 #### B+Tree:多路平衡树PLUS版 非叶子节点之存储关键字和子节点引用,相对于B-Tree少存储了数据,树的路更多一些,树显得更矮胖一些(相同层级能存储更多的数据),查询时IO次数少 叶子节点以链表的方式存储数据,排序能力更强 ## 索引 ### 定义 索引是为了加速数据查询而特定的一种数据结构。 索引由存储引擎实现,不同的库、表均可以有不同的存储引擎。 ### 表数据文件 ```mysql -- 查询数据文件的目录 show variables like 'datadir'; ``` | 存储引擎 | 表结构定义文件 | 索引文件 | 数据文件 | | :------: | :------------: | :------: | :------: | | MYISAM | .frm | .MYI | .MYD | | INNODB | .frm | .ibd | | **注:INNODB的索引文件和数据文件都在 .ibd文件中** ### 索引存储和查询 #### MYISAM ![MYISAM存储引擎索引的存储和查询](MYISAM索引存储.png) MYISAM存储引擎索引和数据是分开存储的,主键索引、辅助索引的查询方式相同 #### INNODB ![INNODB存储引擎索引的存储和查询](INNODB索引存储.png) INNODB存储引擎的索引和数据是集中存储的,辅助索引最终命中的是主键ID,然后再通过主键索引命中数据 ### 索引优化原则 离散型原则:离散型越高,选择性越好 最左匹配原则:联合索引从左向右匹配,单列索引是特殊的联合索引 最少空间原则:宽度小的列优先 ```mysql -- 离散型计算公式,如:性别男、女这种字段离散性差,建索引效果接近于全表扫描 count(distinct column):count(column) ``` ### 覆盖索引 查询的字段完全能在索引关键字中命中,无需扫表直接返回 ## 慢SQL查询日志 ```mysql -- 是否开启慢查询 show variables like 'slow_query_log%'; -- 慢查询日志文件 show variables like 'slow_query_log_file%'; -- 慢查询时间配置,超过这个时间被认为是慢查询 show variables like 'long_query_time'; -- 是否将没有使用索引的查询记录为慢查询日志 show VARIABLES like 'log_queries_not_using_indexes' ``` **日志结构** | 属性 | 描述 | | ------------- | -------------- | | Time | 日志记录时间 | | User@Host | 用户@主机 | | Query_time | 查询耗时 | | Set timestamp | 语句执行时间戳 | | select ··· | 查询语句 | **分析工具** ```shell # 慢查询命令帮助 mysqldumpslow --help # 慢查询分析 mysqldumpslow -t 10 -s at /var/lib/mysql/xxx-slow.log ``` ## 存储引擎 ### csv存储引擎 适用场景:数据的导入导出,编辑数据可以直接操作csv文件 ### Archive存储引擎 适用场景:以ARZ格式存储,数据占用磁盘少,适用于日志记录、大量设备的记录采集等 ### Memory存储引擎 适用场景:热度较高的数据,查询结果从内存中计算。默认大小16M,注意重启会数据丢失。 ### Myisam存储引擎 Mysql5.5版本之前的默认的存储引擎,很多系统表也是使用这个存储引擎,系统临时表也是使用这个存储引擎。 ## 事务 | 隔离级别 | 脏读 | 不可重复读 | 幻读 | 并发度 | | ------------------------------------------ | ---- | ---------- | -------------- | ------ | | Read UnCommited(读未提交) | √ | √ | √ | 高 | | Read Commited(读已提交) | × | √ | √ | 较高 | | **Repeatable Read(可重复读),MYSQL默认** | × | × | 对INNODB不可能 | 中 | | Serializable(串行化) | × | × | × | 低 | 脏读:读到其他事务未提交的数据 不可重复读:同一条多次读取数据不一致,可能数据被其他事务更新后回滚 幻读:多次读取结果集数据量有变化,如范围查询过程中其他事务增加或者删除数据 ### 锁 **注意:InnoDB中,只有通过索引条件检索数据才会使用行锁,否则使用表锁** #### 行锁 ##### 共享锁 共享锁(Share Locks):简称S锁 锁定级别:行锁 加锁方式:lock in share mode 例:select * from user where id = 1 lock in share mode; 特性:在有索引的记录上加锁是行锁,在没有索引的记录上加锁是表锁。其他事务对已加锁的数据可读不可写,即能select、不能update、delete,可以insert ##### 排他锁 排他锁(Exclusive Locks):简称X锁 锁定级别:行锁 加锁方式:INSERT、UPDATE、DELETE语句,for update 特性:在有索引的记录上加锁是行锁,在没有索引的记录上加锁是表锁。其他事务对已加锁的数据可读不可写,即能select、不能update、delete,可以insert 例:update user set age = 20 where id = 1; select * from user where id = 1 for update; **示例** **建表和初始化数据** **注意:以下每个示例都完全基于初始化数据实现,互不干扰。** ```mysql -- 建表 CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `age` smallint(6) NOT NULL, `address` varchar(255) NOT NULL, `phone` varchar(255) NOT NULL, `create_time` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `idx_user_name` (`name`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8; -- 初始化数据 insert into user (name,age,address,phone,create_time) values ('张三',11,'北京','18512345678',CURDATE()); insert into user (name,age,address,phone,create_time) values ('李四',22,'上海','18612345678',CURDATE()); insert into user (name,age,address,phone,create_time) values ('王五',33,'广州','18712345678',CURDATE()); insert into user (name,age,address,phone,create_time) values ('赵六',44,'深圳','18812345678',CURDATE()); ``` **共享锁** session1: ```mysql -- 自动提交 show variables like 'autocommit'; -- 当前session设置不自动提交 set session autocommit = OFF; -- 场景1.使用主键查询,加共享锁(S锁),锁当前行 select * from user where id = 1 lock in SHARE mode; -- 场景2.使用唯一索引查询,加共享锁(S锁),锁当前行 select * from user where name = '张三' lock in SHARE mode; -- 场景3.使用费索引字段查询,加共享锁(S锁),锁表 select * from user where phone = '18512345678'; ``` session2:(使用索引检索数据的场景,针对场景1、场景2) ```mysql -- 插入,成功 insert into user (name,age,address,phone,create_time) values ('测试1',100,'泰国','18412345678',CURDATE()); -- 索引查询,成功 select * from user where id= 1; -- 非查询,成功 select * from user where phone= '18512345678'; -- 索引查询加共享锁,成功 select * from user where id= 1 lock in share mode; -- 非查询加共享锁,成功 select * from user where phone= '18512345678' lock in share mode; -- 带索引条件,删除当前数据,阻塞 delete from user where id = 1; -- 不带索引条件,删除当前数据,阻塞 delete from user where phone= '18512345678'; -- 带索引条件,删除其他数据,成功 delete from user where id = 3; -- 不带索引条件,删除其他数据,阻塞 delete from user where phone= '18812345678'; -- 带索引条件,更新当前数据,阻塞 update user set age = 88 where name = '张三'; -- 带索引条件,更新当前数据,阻塞 update user set age = 77 where phone= '18512345678'; -- 带索引条件,更新其他数据,成功 update user set age = 12 where id = 2; -- 不带索引条件,更新其他数据,阻塞 update user set age = 77 where phone= '18812345678'; ``` session2:(不使用索引检索数据的场景,针对场景3) ```mysql -- 插入,失败 insert into user (name,age,address,phone,create_time) values ('测试1',100,'泰国','18412345678',CURDATE()); -- 索引查询,成功 select * from user where id= 1; -- 非查询,成功 select * from user where phone= '18512345678'; -- 索引查询加共享锁,成功 select * from user where id= 1 lock in share mode; -- 非查询加共享锁,成功 select * from user where phone= '18512345678' lock in share mode; -- 带索引条件,删除当前数据,阻塞 delete from user where id = 1; -- 不带索引条件,删除当前数据,阻塞 delete from user where phone= '18512345678'; -- 带索引条件,删除其他数据,阻塞 delete from user where id = 3; -- 不带索引条件,删除其他数据,阻塞 delete from user where phone= '18812345678'; -- 带索引条件,更新当前数据,阻塞 update user set age = 88 where name = '张三'; -- 带索引条件,更新当前数据,阻塞 update user set age = 77 where phone= '18512345678'; -- 带索引条件,更新其他数据,阻塞 update user set age = 12 where id = 2; -- 不带索引条件,更新其他数据,阻塞 update user set age = 77 where phone= '18812345678'; ``` **排他锁** session1: ```mysql -- 自动提交 show variables like 'autocommit'; -- 当前session设置不自动提交 set session autocommit = OFF; -- 场景1.使用索引作为查询条件,锁行 select * from user where id = 1 for update; -- 场景2.使用索引条件作为更新条件,锁行 update user set age = 999 where id = 1; -- 场景3.使用索引条件作为删除条件,锁行 delete from user where id = 1; -- 场景4.使用非索引条件作为查询条件,锁表 select * from user where phone = '18512345678' ; -- 场景5.使用索引条件作为更新条件,锁表 update user set age = 999 where phone = '18512345678'; -- 场景6.使用索引条件作为删除条件,锁表 delete from user where phone = '18512345678'; ``` session2:(使用索引检索数据的场景,针对场景1、场景2、场景3) ```mysql -- 插入,成功 insert into user (name,age,address,phone,create_time) values ('测试1',100,'泰国','18412345678',CURDATE()); -- 索引查询,成功 select * from user where id= 1; -- 非查询,成功 select * from user where phone= '18512345678'; -- 索引查询加共享锁,阻塞 select * from user where id= 1 lock in share mode; -- 非查询加共享锁,阻塞 select * from user where phone= '18512345678' lock in share mode; -- 带索引条件,删除当前数据,阻塞 delete from user where id = 1; -- 不带索引条件,删除当前数据,阻塞 delete from user where phone= '18512345678'; -- 带索引条件,删除其他数据,成功 delete from user where id = 3; -- 不带索引条件,删除其他数据,阻塞 delete from user where phone= '18812345678'; -- 带索引条件,更新当前数据,阻塞 update user set age = 88 where name = '张三'; -- 带索引条件,更新当前数据,阻塞 update user set age = 77 where phone= '18512345678'; -- 带索引条件,更新其他数据,成功 update user set age = 12 where id = 2; -- 不带索引条件,更新其他数据,阻塞 update user set age = 77 where phone= '18812345678'; ``` session2:(使用索引检索数据的场景,针对场景4、场景5、场景6) ```mysql -- 插入,阻塞 insert into user (name,age,address,phone,create_time) values ('测试1',100,'泰国','18412345678',CURDATE()); -- 索引查询,成功 select * from user where id= 1; -- 非查询,成功 select * from user where phone= '18512345678'; -- 索引查询加共享锁,阻塞 select * from user where id= 1 lock in share mode; -- 非查询加共享锁,阻塞 select * from user where phone= '18512345678' lock in share mode; -- 带索引条件,删除当前数据,阻塞 delete from user where id = 1; -- 不带索引条件,删除当前数据,阻塞 delete from user where phone= '18512345678'; -- 带索引条件,删除其他数据,阻塞 delete from user where id = 3; -- 不带索引条件,删除其他数据,阻塞 delete from user where phone= '18812345678'; -- 带索引条件,更新当前数据,阻塞 update user set age = 88 where name = '张三'; -- 带索引条件,更新当前数据,阻塞 update user set age = 77 where phone= '18512345678'; -- 带索引条件,更新其他数据,阻塞 update user set age = 12 where id = 2; -- 不带索引条件,更新其他数据,阻塞 update user set age = 77 where phone= '18812345678'; ``` **总结** | | 共享锁 | 排他锁 | | :--------: | :----: | :----: | | **共享锁** | √ | × | | **排他锁** | × | × | #### 表锁 ##### 意向共享锁 意向共享锁(Intention Share Locks):表锁,事务准备给数据加入共享锁,必须先取得该表的IS锁,意向共享锁之间是可以相互兼容的 ##### 意向排他锁 意向排他锁(Intention Exclusive Locks):表锁,事务准备给数据加入排他锁,必须先取得该表的IX锁,意向排他锁之间是可以相互兼容的 说明:这两个锁是INNODB自己加的,无需用户干预。 **好处**:无需一行一行数据扫描尝试获取锁,相当于一个信号灯的作用。在火车上厕所不用一个一个开门看有没有人,直接看信号灯就知道了。 ##### 自增锁 自增锁(AUTO-INC Locks):和auto_increment有关,针对自增列自增长的特殊的表锁。 自增列每次会分配一个id值,这个值是连续的。但是如果事务rollback、或者插入失败(如唯一索引冲突),这个值将丢失,可能造成id不连续。 ```mysql -- 查看自增列配置,不建议更改此值 show variables like 'innodb_autoinc_lock_mode'; ``` #### 行锁算法 ```mysql -- 建表 create table test( id int(11) not null primary key, name int(11) not null ); -- 初始化数据 insert into test values(1,1); insert into test values(4,4); insert into test values(7,7); insert into test values(10,10); insert into test values (12,12); ``` ##### 临键锁 临键锁(Next-key Locks):**行锁的默认算法** ```mysql -- session1: -- 默认关闭自动提交 set session autocommit = 'OFF'; -- 使用索引 && 查询区间的数据 && 能命中数据,使用临键锁 -- 临键锁区间左开右闭,将区间分为:(-∞,1],(1,4],(4,7],(7,10],(10,12],(12,+∞) -- 当前锁定(4,7],(7,10]区间 select * from test where id > 4 and id < 9 for update; ``` ```mysql -- session2: -- 正常 select * from test where id = 4 for update; -- 阻塞 select * from test where id = 7 for update; -- 阻塞 select * from test where id = 10 for update; -- 正常 select * from test where id = 12 for update; ``` ##### 间隙锁 ```java // TODO 间隙锁有问题,可能理解的不对 ``` 间隙锁(Gap Locks) ```mysql -- session1: -- 默认关闭自动提交 set session autocommit = 'OFF'; -- 使用索引 && 不能命中数据,从临键锁降为间隙锁 -- 间隙锁区间左开右开,将区间分为(-∞,1),(1,4),(4,7),(7,10),(10,12),(12,+∞) -- 场景1,锁定区间:(4,7],这块和老师讲的不一样 select * from test where id > 4 and id < 6 for update; -- 场景2,锁定区间:(4,7) select * from test where id = 6 for update; ``` ```mysql -- 场景1,session2: -- 正常 select * from test where id = 4 for update; -- 阻塞 insert into test (id,name) values (5,5); -- 阻塞 insert into test (id,name) values (6,6); -- 阻塞 select * from test where id = 7 for update; -- 正常 insert into test (id,name) values (8,8); -- 正常 select * from test where id = 10 for update; ``` ```mysql -- 场景2,session2: -- 正常 select * from test where id = 4 for update; -- 阻塞 insert into test (id,name) values (5,5); -- 阻塞 insert into test (id,name) values (6,6); -- 正常 select * from test where id = 7 for update; -- 正常 select * from test where id = 10 for update; ``` ##### 记录锁 记录锁(Record Locks) ```mysql -- session1: -- 默认关闭自动提交 set session autocommit = 'OFF'; -- 使用索引 && 精准查询 && 命中数据,使用记录锁 -- 锁定id=7的记录 select * from test where id = 7 for update; ``` ```mysql -- session2:阻塞 select * from test where id = 7 for update; ``` #### 锁实践 ##### 解决脏读问题 加排他锁,使用快照读,只能读到事务修改前的数据 ##### 解决不可重复读问题 当前事务加共享锁,其他事务只能读不能改 ##### 解决幻读问题 使用间隙锁,锁定区间 ##### 死锁 ###### 场景 多个事务并发操作 && 相互等待对方释放锁 ###### 示例 ```mysql -- session1: -- 执行顺序0 set session autocommit = 'OFF'; -- 执行顺序1 select * from table1 where id = 1 for update; -- 执行顺序4 select * from table2 where id = 1 for update; ``` ```mysql -- session2: -- 执行顺序0 set session autocommit = 'OFF'; -- 执行顺序2 select * from table2 where id = 1 for update; -- 执行顺序3 select * from table1 where id = 1 fro update; ``` ```mysql -- mysql提示 [SQL] select * from sys_config where id = 3 for update; [Err] 1213 - Deadlock found when trying to get lock; try restarting transaction ``` ###### 解决方案 类似的业务逻辑尽量按照一定的顺序访问表和行 尽量减少大事务,精简为小事务 同一个事务尽可能一次性锁定所有的资源,减少死锁的概率 降低事务的隔离级别 为表创建合适的索引,索引走行锁,没有索引会走表锁 ### MVCC MVCC(Multi-version Concurrency Control):多版本并发控制 并发访问(读或写)数据库时,对正在操作的事务内处理的数据做多版本的管理。以达到用来避免写操作的阻塞,从而引发读操作的并发问题。 **Mysql默认会为记录添加两个隐藏字段,一个标识插入事务ID(db_trx_id),一个标识删除事务ID(db_roll_pt)** #### 初始化 ```mysql -- 建表 CREATE TABLE `test_mvcc` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ``` #### INSERT ```mysql -- 假定当前事务ID = 1 begin; insert into test_mvcc (name) values ('张三'); insert into test_mvcc (name) values ('李四'); commit; -- 效果:记录db_trx_id = 当前事务ID id name db_trx_id db_roll_pt 1 张三 1 NULL 2 李四 1 NULL ``` #### DELETE ```mysql -- 假定当前事务ID = 22 begin; delete from user where id = 1; commit; -- 效果:将事务ID当前记录的db_roll_pt id name db_trx_id db_roll_pt 1 张三 1 22 2 李四 1 NULL ``` #### UPDATE ```mysql -- 假定当前事务ID = 33 begin; update user set name = '王五' where id = 1; commit; -- 效果:1.COPY当前数据并写入当前事务ID 2.将原数据db_roll_pt修改为当前事务ID id name db_trx_id db_roll_pt 1 张三 1 33 2 李四 1 NULL 1 张三 33 NULL ``` #### SELECT ```mysql -- 假定当前事务ID = 40 begin; select * from user where id = 1; commit; -- 效果:1.db_trx_id小于等于当前事务ID 2.db_roll_pt大于当前事务ID或者为NULL的 -- db_trx_id小于当前事务ID代表事务之前就已经存在 -- db_trx_id等于当前事务ID代表当前事务插入或修改的 -- db_roll_pt大于当前事务ID代表当前事务操作的 -- db_roll_pt为NULL代表事务开始之前没有被删除 id name 1 张三 ``` ### 日志 #### Undo Log **目的**:原子性 Undo即取消,以撤销为目的。在事务操作开始之前,对数据做备份,以便事务出现错误或者rollback时将数据恢复到事务操作之前的状态。 undo log中的数据可作为旧版本快照供其他事务并发进行快照读 ![](Undo Log.png) **快照读**:SQL读取的是快照版本,也就是历史版本,普通的SELECT就是快照读。 在INNODB中,快照读是由cache(原本数据) + undo(事务修改过的数据)两部分组成。 **当前读**:UPDATE、DELETE、INSERT、SELECT ... LOCK IN SHARE MODEL、SELECT ... FOR UPDATE都是当前读。 #### Redo Log **目的**:持久化 Redo即重做,以恢复数据为目的。在事务提交之前,先写入Redo Log。若发生故障,在mysql重启的时候会将脏页写入磁盘,从而达到持久性的目的。 Redo Log并不是事务提交的时候才写入的,而是在事务提交的过程中,便开始写入Redo Log。 **相关参数** ```mysql -- 数据文件目录 show variables like 'datadir'; -- redo log存储目录,文件为:ib_logfile0、ib_logfile1 show variables like 'innodb_log_group_home_dir'; -- redo log日志文件组数量,默认为2 show variables like 'innodb_log_files_in_group'; -- redo log每个文件最大存储量,默认为48M show variables like 'innodb_log_file_size'; -- redo log在cache/buffer中的buffer池大小,默认为16M show variables like 'innodb_log_buffer_size'; -- redo log的持久化策略 show variables like 'Innodb_flush_log_at_trx_commit'; ``` **持久化策略**: 0:每秒提交Redo buffer --> Redo log OS cache --> flush cache to disk,可能丢失1s的数据 1:每次提交事务执行Redo buffer --> Redo log OS cache --> flush cache to disk,最安全但性能最差 2:每次提交事务执行Redo buffer --> Redo log OS cache,下一秒执行flush cache to disk操作 ## 配置优化 ```shell # 寻找配置文件位置和加载顺序 mysql --help # 系统句柄数 /etc/security/limits.conf ulimit -a # mysql句柄数 /usr/lib/systemd/system/mysqld.service ``` ```mysql -- 最大连接数 show variables like 'max_connections'; # mysql base目录 show variables like 'basedir'; -- 排序缓冲区大小 show variables like 'sort_buffer_size'; -- join缓冲区大小 show variables like 'join_buffer_size'; -- mysql connection占用内存:连接数 * (sort_buffer_size + join_buffer_size) -- innodb buffer/cache大小,包含数据缓存、索引缓存、缓冲数据、内部结构,默认为128M -- 参考公式:innodb_buffer_pool_size = (总物理内存 - 系统运行所用 - connection所用) * 90% show variables like 'innodb_buffer_pool_size'; -- 服务端关闭非交互连接之前等等的秒数 show VARIABLES like 'wait_timeout'; -- innodb同时可以打开的表的个数 show variables like 'innodb_open_files'; -- 后台写线程数配置 show variables like 'innodb_write_io_threads'; -- 后台读线程数配置 show variables like 'innodb_read_io_threads'; -- 事务回滚之前可以等待锁定的超时秒数 show variables like 'innodb_lock_wait_timeout'; ```