Skip to content

Commit

Permalink
mysql +1
Browse files Browse the repository at this point in the history
  • Loading branch information
Q10Viking committed Mar 20, 2024
1 parent 446ea76 commit e6a613c
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 0 deletions.
156 changes: 156 additions & 0 deletions docs/MySQL/44 添加索引真的不会锁表吗.md
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操作期间不允许对锁表进行任何操作
19 changes: 19 additions & 0 deletions docs/MySQL/45 覆盖索引.md
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,并且在内存中更高效地处理查询操作。因此,在设计数据库索引时,可以考虑创建覆盖索引来优化相关的查询。
18 changes: 18 additions & 0 deletions docs/MySQL/46 数据库CPU飙升解决方式.md
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过度使用。可以通过监控系统资源使用情况,调整或增加资源配置,以满足数据库的需求。

0 comments on commit e6a613c

Please sign in to comment.