-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Q10Viking
committed
Mar 20, 2024
1 parent
446ea76
commit e6a613c
Showing
3 changed files
with
193 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
--- | ||
sidebarDepth: 3 | ||
sidebar: auto | ||
prev: | ||
text: Back To 目录 | ||
link: /MySQL/ | ||
typora-root-url: ..\.vuepress\public | ||
--- | ||
|
||
|
||
|
||
## MySQL DDL执行方式 | ||
|
||
MySQL5.5以及之前的版本,通常更改数据表结构操作(DDL)会阻塞对表数据的增删改操作(DML)。 | ||
MySQL5.6提供Online DDL之后可支持DDL与DML操作同时执行,降低了DDL期间对业务延迟带来的影响 | ||
|
||
``` | ||
数据操作语言DML(Data Manipulation Language) | ||
数据库模式定义语言DDL(Data Definition Language) | ||
``` | ||
|
||
### 数据准备 | ||
|
||
```sql | ||
DROP TABLE IF EXISTS `scores`; | ||
CREATE TABLE scores ( | ||
id INT NOT NULL AUTO_INCREMENT COMMENT '序号', | ||
student_id INT NOT NULL COMMENT '学号', | ||
course_name VARCHAR(50) NOT NULL COMMENT '课程名称', | ||
score INT NOT NULL COMMENT '分数', | ||
remarks varchar(400) COMMENT '备注', | ||
PRIMARY KEY (id) | ||
);ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; | ||
|
||
select count(*) from scores; --240w | ||
``` | ||
|
||
### 使用ALGORITHM = INPLACE,Lock = NONE; | ||
|
||
使用INPLACE,NONE时不阻塞其他事务的DML操作。 | ||
|
||
```sql | ||
ALTER TABLE scores drop index idx_student_id; | ||
事务A使用online ddl添加索引: | ||
begin; | ||
ALTER TABLE scores ADD index idx_student_id (student_id) , ALGORITHM=INPLACE, LOCK=NONE; | ||
commit; | ||
|
||
1.事务A使用online ddl添加索引,事务B进行查询,可以正常读取: | ||
begin; | ||
select * from scores where id = 1 ; | ||
commit; | ||
|
||
|
||
2.事务A使用online ddl添加索引,事务B进行修改,可以正常修改: | ||
begin; | ||
update scores set course_name = '张三' where id = 1 ; | ||
commit; | ||
|
||
3.事务A使用online ddl添加索引,事务B进行删除,可以正常删除: | ||
begin; | ||
delete from scores where id = 1; | ||
commit | ||
|
||
4.事务A使用online ddl添加索引,事务B进行插入,可以正常插入: | ||
begin; | ||
INSERT INTO `scores` (`id`, `student_id`, `course_name`, `score`, `remarks`) | ||
VALUES ('1', '1', 'mock_Chinese1', '71', 'mock_remarks_mock_remarks_mock_remarks_mock_remarks_mock_remarks_mock_remarks_mock_remarks_mock_remarks_mock_remarks_mock_remarks_mock_remarks'); | ||
commit; | ||
``` | ||
|
||
### 使用ALGORITHM = COPY,Lock = EXCLUSIVE; | ||
|
||
使用COPY,EXCLUSIVE时,会阻塞其他事务的DML操作。当DDL事务提交后,其他事务才能正常DML操作 | ||
|
||
```sql | ||
ALTER TABLE scores drop index idx_student_id; | ||
事务A使用online ddl添加索引: | ||
begin; | ||
ALTER TABLE scores ADD index idx_student_id (student_id) , ALGORITHM=COPY, LOCK=EXCLUSIVE; | ||
commit; | ||
|
||
1.事务A使用online ddl添加索引,事务B进行查询出现阻塞,需等事务A结束: | ||
begin; | ||
select * from scores where id = 1 ; | ||
commit; | ||
|
||
2.事务A使用online ddl添加索引,事务B进行修改出现阻塞,需等事务A结束: | ||
begin; | ||
update scores set course_name = '张三' where id = 1 ; | ||
commit; | ||
|
||
3.事务A使用online ddl添加索引,事务B进行删除出现阻塞,需等事务A结束: | ||
begin; | ||
delete from scores where id = 1; | ||
commit | ||
|
||
4.事务A使用online ddl添加索引,事务B进行插入出现阻塞,需等事务A结束: | ||
begin; | ||
INSERT INTO `scores` (`id`, `student_id`, `course_name`, `score`, `remarks`) | ||
VALUES ('1', '1', 'mock_Chinese1', '71', 'mock_remarks_mock_remarks_mock_remarks_mock_remarks_mock_remarks_mock_remarks_mock_remarks_mock_remarks_mock_remarks_mock_remarks_mock_remarks'); | ||
commit; | ||
``` | ||
|
||
### 模拟online ddl执行时,有其他事务持有MDL锁 | ||
|
||
Online DDL 过程必须等待已经持有MDL锁的并发事务提交或者回滚才能继续执行 | ||
|
||
```sql | ||
ALTER TABLE scores drop index idx_student_id; | ||
事务A进行查询,不提交事务: | ||
begin; | ||
select * from scores; | ||
--commit; | ||
|
||
事务B使用online ddl添加索引,阻塞中: | ||
begin; | ||
ALTER TABLE scores ADD index idx_student_id (student_id) , ALGORITHM=INPLACE, LOCK=NONE; | ||
commit; | ||
|
||
事务C进行查询,阻塞中: | ||
select * from scores where id = 1 ; | ||
|
||
查询进程信息: | ||
show processlist; | ||
``` | ||
|
||
|
||
|
||
## 参数 | ||
|
||
### **ALGORITHM:** | ||
|
||
**ALGORITHM=DEFAULT:**默认算法,使用最高效的算法 | ||
**ALGORITHM=INPLACE:**在原表上进行更改,不需要生成临时表,不需要进行数据copy的过程。 | ||
添加索引步骤: | ||
1.创建索引(二级索引)数据字典 | ||
2.加共享表锁,禁止DML,允许查询 | ||
3.读取聚簇索引,构造新的索引项,排序并插入新索引 | ||
4.等待打开当前表的所有只读事务提交 | ||
5.创建索引结束 | ||
|
||
**ALGORITHM=COPY:**最原始的方式,通过临时表创建索引,需要多一倍存储,还有更多的IO(类似5.6版本之前的处理过程) | ||
添加索引步骤: | ||
1.新建带索引(主键索引)的临时表 | ||
2.锁原表,禁止DML,允许查询 | ||
3.将原表数据拷贝到临时表 | ||
4.禁止读写,进行rename,升级字典锁 | ||
5.完成创建索引操作 | ||
|
||
### **LOCK:** | ||
|
||
**LOCK=DEFAULT:**默认方式,MySQL自行判断使用哪种LOCK模式,尽量不锁表 | ||
**LOCK=NONE:**无锁:允许Online DDL期间进行并发读写操作。如果Online DDL操作不支持对表的继续写入,则DDL操作失败,对表修改无效 | ||
**LOCK=SHARED:**共享锁:Online DDL操作期间堵塞写入,不影响读取 | ||
**LOCK=EXCLUSIVE:**排它锁:Online DDL操作期间不允许对锁表进行任何操作 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
--- | ||
sidebarDepth: 3 | ||
sidebar: auto | ||
prev: | ||
text: Back To 目录 | ||
link: /MySQL/ | ||
typora-root-url: ..\.vuepress\public | ||
--- | ||
|
||
覆盖索引是指一个索引包含了查询所需的所有列,而无需访问表的实际数据页。 | ||
|
||
当数据库系统执行查询时,通常需要从磁盘中读取数据页到内存中才能进行处理。而如果使用了覆盖索引,由于索引已经包含了查询所需的所有列的值,数据库系统可以直接通过索引来获取这些值,而不需要额外地读取数据页。这样可以减少磁盘 I/O 的次数和数据在内存中的占用,提高查询的效率。 | ||
|
||
**覆盖索引通常适用于以下场景:** | ||
|
||
1. 查询语句只需要返回索引列中的数据,而不需要访问其他列的值。 | ||
2. 查询语句中的条件过滤、排序或分组的列都在同一个索引上。 | ||
|
||
**总结来说:**使用覆盖索引可以减少数据库系统的工作量,提高查询的性能。它可以避免不必要的数据读取操作,减少磁盘 I/O,并且在内存中更高效地处理查询操作。因此,在设计数据库索引时,可以考虑创建覆盖索引来优化相关的查询。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
--- | ||
sidebarDepth: 3 | ||
sidebar: auto | ||
prev: | ||
text: Back To 目录 | ||
link: /MySQL/ | ||
typora-root-url: ..\.vuepress\public | ||
--- | ||
|
||
|
||
|
||
|
||
|
||
1. **查询性能问题:**某些查询可能没有被正确地优化,导致**查询执行时间过长,从而占用大量的CPU资源**。可以通过查看**慢查询日志和执行计划**来分析问题查询,并进行**索引优化、重写查询语句**或调整数据库配置等方式来改善查询性能。 | ||
2. **数据库连接问题:**如果存在大量的数据库连接并发访问,可能会造成CPU负载过高。可以检查应用程序连接池的配置情况、数据库连接数限制以及是否有闲置的连接未关闭等问题,并进行相应调整。 | ||
3. **锁和死锁问题:**并发事务之间的锁竞争或死锁可能导致CPU飙升。可以通过查看数据库的锁状态、死锁日志以及事务并发控制的设置来解决锁相关的问题。 | ||
4. **配置问题:**不合理的数据库配置可能导致CPU资源浪费和效率低下。可以检查MySQL的配置参数,如缓冲区大小、并发连接数、线程池大小等是否合理设置,并进行相应调整。 | ||
5. **资源竞争:**如果服务器的物理资源(如内存、磁盘I/O)不足或受限,可能会导致CPU过度使用。可以通过监控系统资源使用情况,调整或增加资源配置,以满足数据库的需求。 |