1) DB Lock ์ฌํ
(1) ๊ฐ์
- RDBMS ์ค ํ๋์ธ MySQL์ MariaDB์ ๊ฐ์ด ์คํ ๋ฆฌ์ง ์์ง์ผ๋ก InnoDB๋ฅผ ์ฌ์ฉํ๊ณ ์์ด InnoDB ๋ผ๊ณ ๋ ๋ถ๋ฆฐ๋ค.
- ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ์ ์งํ๋ ๋ฐ ์์ด ํต์ฌ์ ์ธ ํธ๋์ญ์ ๋ชจ๋ธ (Transaction Model), ๊ฒฉ๋ฆฌ์ฑ ์์ค (Isolation Level), DB Lock์ ์คํ ๋ฆฌ์ง ์์ง์ธ InnoDB์ ์ข ์๋๊ธฐ ๋๋ฌธ์ MySQL๊ณผ MariaDB๋ InnoDB์ ํธ๋์ญ์ ๋ชจ๋ธ, ๊ฒฉ๋ฆฌ์ฑ ์์ค, DB Lock ๋ฉ์ปค๋์ฆ์ ๋ฐ๋ฅด๊ฒ ๋๋ค.
- ๋ํ, ์ฌ๊ธฐ์ ๊น๊ฒ ๋ค์ด๊ฐ๋ณด์๋ฉด MySQL์์ ์ฌ์ฉํ๋ DB Lock์ ํฌ๊ฒ MySQL ์์ง์์ ์ ๊ณตํ๋ DB Lock์ด ์๊ณ , ์คํ ๋ฆฌ์ง ์์ง์์ ์ ๊ณตํ๋ DB Lock์ด ์๋ค.
- MySQL ์์ง์์ ์ ๊ณตํ๋ DB Lock๊ณผ InnoDB ์คํ ๋ฆฌ์ง ์์ง์์ ์ ๊ณตํ๋ DB Lock์ ์๋์ ๊ฐ๋ค.
- MySQL ์์ง ๋ ๋ฒจ์ Locks
โ Global Locks
โก Table Locks
โข Named Locks
โฃ Metadata Locks
- ์คํ ๋ฆฌ์ง ์์ง ๋ ๋ฒจ์ Locks
โ Shared and Exclusive Locks
โก Intention Locks
โข Record Locks
โฃ Gap Locks
โค Next-key Locks
โฅ Insertion Intention Locks
โฆ Auto-INC Locks
โง Predicate Locks for Spatial Indexes
(1-1) InnoDB ์คํ ๋ฆฌ์ง ์์ง ์ ๊ธ ๋ฐฉ์
- InnoDB ์คํ ๋ฆฌ์ง ์์ง ๋ ๋ฒจ์์ ์ ๊ณต๋๋ DB Lock์ MySQL์์ ์ ๊ณตํ๋ DB Lock ๊ณผ๋ ๋ณ๊ฐ๋ก ์์ง ๋ด๋ถ์์ ๋ ์ฝ๋ ๊ธฐ๋ฐ์ ์ ๊ธ ๋ฐฉ์์ ์ฌ์ฉํ๋ค.
- ๋ณดํต ๋ช ์์ ์ผ๋ก ์ ๊ธ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ ๋๋ฌผ๋ฉฐ, ๊ฒฉ๋ฆฌ ์์ค์ ๋ฐ๋ผ ๋ฌต์์ ์ผ๋ก ์ ๊ธ์ด ์ฌ์ฉ๋์ด์ง๋ค.
- InnoDB ์์ง์์๋ ๋น๊ด์ ์ ๊ธ ๋ฐฉ์์ ์ฌ์ฉํ๋ค.
โ ๋น๊ด์ ๋์์ฑ ์ ์ด (PCC, Pessimistic Concurrency Control)
๋น๊ด์ ๋ฝ์ ํ์ฌ ํธ๋์ญ์ ์์ ๋ณ๊ฒฝํ๊ณ ์ ํ๋ ๋ ์ฝ๋์ ๋ํด ์ ๊ธ์ ๋จผ์ ํ๋ํ๊ณ ๋ณ๊ฒฝ ์์ ์ ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ ๋งํ๋ค.
์ด ์ฒ๋ฆฌ ๋ฐฉ์์ ์ด๋ฆ์์๋ ๋๋ ์ ์๋ฏ์ด, “ํ์ฌ ๋ณ๊ฒฝํ๊ณ ์ ํ๋ ๋ ์ฝ๋๋ฅผ ๋ค๋ฅธ ํธ๋์ญ์ ์์๋ ๋ณ๊ฒฝํ ์ ์๋ค” ๋ผ๋ ๋น๊ด์ ์ธ ๊ฐ์ ์ ํ๊ธฐ ๋๋ฌธ์ ๋จผ์ ์ ๊ธ์ ํ๋ํ๋ค.
์ผ๋ฐ์ ์ผ๋ก Shared Lock, Exclusive Lock์ ํตํด ์ด๋ฅผ ๊ตฌํํ๋ค.
โก ๋๊ด์ ๋์์ฑ ์ ์ด (OCC, Optimistic Concurrency Control)
๋๊ด์ ๋ฝ์ ํธ๋์ญ์ ์ด ๊ฐ์ ๋ ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ ๊ฐ๋ฅ์ฑ์ ์๋นํ ํฌ๋ฐํ ๊ฒ์ด๋ผ๊ณ “๋๊ด์ ”์ผ๋ก ๊ฐ์ ํ๊ธฐ ๋๋ฌธ์ ๋ณ๊ฒฝ ์์ ์ ์ํํ๊ณ ๋ง์ง๋ง์ ์ ๊ธ ์ถฉ๋์ด ์์๋ ์ง๋ฅผ ํ์ธํด ๋ฌธ์ ๊ฐ ์์๋ค๋ฉด Rollback ์ฒ๋ฆฌ๋ฅผ ํ๋ ๋ฐฉ์์ ๋งํ๋ค.
(1-2) ์ค์ต์ ์ํ ์ด๊ธฐ ํ ์ด๋ธ, ์ด๊ธฐ ๋ฐ์ดํฐ ์์ฑ
- MySQL์์ ์ ๊ณตํ๋ DB Lock, ์คํ ๋ฆฌ์ง ์์ง ๋ ๋ฒจ์์ ์ ๊ณตํ๋ DB Lock์ ์ค์ต์ ์ํด ์ด๊ธฐ ํ ์ด๋ธ๊ณผ ๋ฐ์ดํฐ๋ฅผ ์์ฑํ๋ค.
- ๋ํ, ์ํํ ์ค์ต์ ์ํด ๋ฏธ๋ฆฌ DB ์ธ์ ์ 2๊ฐ ์ค๋นํด๋๊ณ AutoCommit ๊ธฐ๋ฅ์ ๋๊ณ ๊ฒฉ๋ฆฌ ์์ค์ “Read-Uncommitted” ์ผ๋ก ์ค์ ํ๋ค.
- ๋ง์ฝ, ๊ฒฉ๋ฆฌ์ฑ ์์ค์ ๋ํด ๋ชจ๋ฅธ๋ค๋ฉด https://shuu.tistory.com/76 ์ฐธ๊ณ ํ์!
// ํ
์ด๋ธ ์์ฑ
CREATE TABLE EMP (
ID INT not null auto_increment,
NAME VARCHAR(100) not null,
JOB VARCHAR(30) not null,
primary key (ID));
// ์ด๊ธฐ ๋ฐ์ดํฐ ์์ฑ
insert into EMP values (1, "userA", 'Student');
insert into EMP values (2, "userB", 'Student');
insert into EMP values (3, "userC", 'Student');
// ํธ๋์ญ์
๊ฒฉ๋ฆฌ ์์ค ์กฐํ
show variables like 'tx_isolation';
// Autocommit ์ค์ ๊ฐ ํ์ธ
show variables like 'autocommit%';
// ํธ๋์ญ์
๊ฒฉ๋ฆฌ ์์ค ์์
set tx_isolation = 'READ-UNCOMMITTED';
// Autocommit ๋๊ธฐ
SET AUTOCOMMIT = FALSE;
(2) MySQL ์์ง ๋ ๋ฒจ์ Lock
(2-1) Global Locks
- “Flush Tables with read lock” ๋ช ๋ น์ผ๋ก Lock ํ๋ํ ์ ์๊ณ , ๊ฐ์ฅ ๋ฒ์๊ฐ ํฐ Lock์ผ๋ก ์๋ฒ ์ ์ฒด์ ์ํฅ์ ๋ฏธ์น๋ค.
- ํ๋์ ์ธ์ ์์ ๊ธ๋ก๋ฒ ๋ฝ์ ํ๋ํ๋ฉด ๋ค๋ฅธ ์ธ์ ์์ Select๋ฅผ ์ ์ธํ ๋๋ถ๋ถ์ DDL, DML ๋ฌธ์ฅ ์คํ ์, ๊ธ๋ก๋ฒ ๋ฝ์ด ํด์ ๋ ๋๊น์ง ๊ณ์ ๋๊ธฐ ์ํ๋ก ๋จ๊ฒ ๋๋ค.
- MySQL ์๋ฒ ์ ์ฒด์ ์ํฅ์ ์ฃผ๊ธฐ ๋๋ฌธ์ ์์ ์ค์ธ ํ ์ด๋ธ์ด๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋์ด์ ๋์ผํ๊ฒ ์ํฅ์ ๋ผ์น๊ฒ ๋๋ค.
- ๋ง์ฝ, ๊ธ๋ก๋ฒ ๋ฝ์ด ์คํ๋๊ธฐ ์ ์ ๋ฒ ํ ๋ฝ์ด ๊ฑธ๋ฆฐ SQL์ด ์คํ๋๋ค๋ฉด ๊ธฐ์กด์ ๋ฒ ํ ๋ฝ์ด ์์ ํ ํด์ ๋ ์ดํ์ ๊ธ๋ก๋ฒ ๋ฝ์ด ๊ฑธ๋ฆฌ๊ฒ ๋๋ค.
- ์ฆ, ์คํ ์ค์ธ ๋ชจ๋ ์ฟผ๋ฆฌ๊ฐ ์๋ฃ๋์ด์ผ๋ง ๊ธ๋ก๋ฒ ๋ฝ์ ํ๋ํ ์ ์๋ ๊ฒ์ด๋ฉฐ, MySQL 8.0 ๋ฒ์ ์ด์๋ถํฐ๋ Xtrabackup, Enterprise Backup ๊ฐ์ด ๋ฐฑ์ ๋ฝ์ด๋ผ๋ ์กฐ๊ธ ๋ ๊ฐ๋ฒผ์ด ๋ฝ์ด ์ถ๊ฐ๋์๋ค.
[์ธ์
1, 2 ๊ณตํต]
set tx_isolation = 'READ-UNCOMMITTED';
SET AUTOCOMMIT = FALSE;
START TRANSACTION;
[์ธ์
1]
Flush Tables with read lock;
[์ธ์
2]
MariaDB [mysql]> insert into emp values (4, 'userD', 'student');
→ ๋๊ธฐ ์ํ๋ก ๋น ์ง๊ฒ ๋๊ณ , ์ธ์
1์์ “unlock tables“ ํด์ฃผ์ด์ผ ์์ฒญ์ด ์ฒ๋ฆฌ๋๋ค.
(2-2) Table Locks
- ํ ์ด๋ธ ๋ฝ์ ๊ฒฝ์ฐ, ํ ์ด๋ธ ๋จ์๋ก ์ค์ ํ๋ Lock ์ด๋ฉฐ ๋ช ์์ (Explicit), ์์์ (implicit) ๋ฝ์ ํ๋ํ ์ ์๋ค.
- ๋ช ์์ ๋ฝ์ ๊ฒฝ์ฐ๋ “Lock Tables ํ ์ด๋ธ๋ช [Read | Write]” ๋ช ๋ น์ผ๋ก Lock ํ๋ํ ์ ์๊ณ , ๋ฌต์์ ๋ฝ์ ๊ฒฝ์ฐ ํ ์ด๋ธ์ ๋ณ๊ฒฝํ๋ ์ฟผ๋ฆฌ๋ฅผ ์คํํ์ ๋ MySQL ์๋ฒ๊ฐ ํด๋น ํ ์ด๋ธ์ Lock์ ์ค์ ํ๊ณ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ ๋ค์ ๋ฐ๋ก Lock์ ํด์ ํ๋ ํํ๋ก ์ฌ์ฉ๋๋ค.
- ์๋์ผ๋ก Lock ์ค์ ๋ฐ ํด์ ๊ฐ ์ผ์ด๋๊ธฐ ๋๋ฌธ์ ํธ๋ฆฌํ์ง๋ง InnoDB์ ๊ฒฝ์ฐ ๋ ์ฝ๋ ๊ธฐ๋ฐ Lock์ ์ ๊ณตํ๊ธฐ ๋๋ฌธ์ ํ ์ด๋ธ ๋ฝ์ด ๋ฐ์ํ๋๋ผ๋ DML์์๋ ๋ฌด์๋๊ณ DDL ์์๋ง ์ํฅ์ ์ค๋ค.
[์ธ์
1, 2 ๊ณตํต]
set tx_isolation = 'READ-UNCOMMITTED';
SET AUTOCOMMIT = FALSE;
START TRANSACTION;
[์ธ์
1]
LOCK TABLES emp Read;
SELECT * from mysql.user;
→ ์ธ์
1์์ emp ํ
์ด๋ธ์ ๋ํ ํ
์ด๋ธ ๋ฝ (Read)์ ์ค์ ํ๋ค.
→ ํ
์ด๋ธ ๋ฝ์ ๊ธฐ๋ณธ ์์น์ ์ ๊ทผ ํ
์ด๋ธ ์ธ์ ํ
์ด๋ธ์ ์ ๊ทผ์ด ๋ถ๊ฐ๋ฅํ๋ฏ๋ก user ํ
์ด๋ธ์ ์ ๊ทผํ ์ ์๋ค.
[์ธ์
2]
LOCK TABLES emp Read;
→ ๋ค๋ฅธ ์ธ์
์ด ๋์์ ๊ฐ์ ํ
์ด๋ธ์ ๋ํ Read ๋ฝ์ ํ๋ํ ์ ์์ผ๋ฏ๋ก ์ธ์
2์์ emp ํ
์ด๋ธ์ ํ
์ด๋ธ ๋ฝ(Read)์ ์ค์ ํ ์ ์๋ค.
[์ธ์
1, 2 ๊ณตํต]
SELECT * FROM emp;
INSERT INTO emp VALUES (4, 'userD', 'student');
→ ์ธ์
1, 2์์ emp ํ
์ด๋ธ์ ํ
์ด๋ธ ๋ฝ (Read)์ ์ค์ ํ์ฌ emp ํ
์ด๋ธ์ ์กฐํํ ์๋ ์์ง๋ง ์์ , ์ญ์ , ์ถ๊ฐ๋ ๋ถ๊ฐ๋ฅํ๋ค.
→ ๊ทธ๋ฆฌ๊ณ emp ํ
์ด๋ธ์ ํ
์ด๋ธ ๋ฝ (Read)์ด ๊ฑธ๋ ค์๊ธฐ ๋๋ฌธ์ ํด๋น ๋ฝ์ด ํด์ ๋๊ธฐ ์ ๊น์ง ํด๋น ํ
์ด๋ธ์ ํ
์ด๋ธ ๋ฝ (Write)์ ์ค์ ํ ์๋ ์๋ค.
[์ธ์
1, 2 ๊ณตํต]
UNLOCK TABLES;
→ ํ
์ด๋ธ ๋ฝ (Write) ์ค์ต์ ์ํด, ๊ธฐ์กด์ ์ค์ ํ ํ
์ด๋ธ ๋ฝ (Read)๋ ํด์ ํ๋ค.
[์ธ์
1]
LOCK TABLES emp Write;
INSERT INTO emp VALUES (4, 'userD', 'student');
→ ์ธ์
1์์ emp ํ
์ด๋ธ์ ํ
์ด๋ธ ๋ฝ (Write)์ ์ค์ ํ๊ณ ํด๋น ํ
์ด๋ธ์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ ์ ์๋ค.
[์ธ์
2]
LOCK TABLES emp Write;
INSERT INTO emp VALUES (4, 'userD', 'student');
SELECT * FROM emp;
→ emp ํ
์ด๋ธ์๋ ์ด๋ฏธ ์ธ์
1์์ ํ
์ด๋ธ ๋ฝ (Write)์ด ์ค์ ๋์ด ์ธ์
2์์ emp ํ
์ด๋ธ์ ํ
์ด๋ธ ๋ฝ (Read, Write)์ ์ค์ ํ ์ ์๋ค.
(2-3) Named Locks
- ๋ค์๋ ๋ฝ์ ๊ฒฝ์ฐ, ํ ์ด๋ธ ๋ฐ ๋ ์ฝ๋, ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฐ์ฒด๊ฐ ์๋ ์ฌ์ฉ์๊ฐ ์ง์ ํ “์์์ ๋ฌธ์์ด”์ ๋ํด Lock์ ํ๋ํ๊ณ ๋ฐ๋ฉํ๋ ๋ฐฉ์์ผ๋ก ํ ์ธ์ ์ด Lock์ ํ๋ํ๋ค๋ฉด ๋ค๋ฅธ ์ธ์ ์ ํด๋น ์ธ์ ์ด Lock์ ํด์ ํ ์ดํ์ ํ๋ํ ์ ์๋ค.
→ ๋ค์๋ ๋ฝ ์ค์ : GET_LOCK(๋ฌธ์์ด), ๋ค์๋ ๋ฝ ํด์ : RELEASE_LOCK(๋ฌธ์์ด)
- Lock์ ์ด๋ฆ์ ์ง์ ํ์ฌ ์ ํ๋ฆฌ์ผ์ด์
์๋ฒ์์ ์ ์ด๊ฐ ๊ฐ๋ฅํ๋ฉฐ ๋จ์ ์ผ๋ก๋ Lock์ด ์๋์ผ๋ก ํด์ ๋์ง ์๊ธฐ ๋๋ฌธ์ ๋ณ๋์ ๋ช
๋ น์ด๋ก ํด์ ๋ฅผ
์ํํ๊ฑฐ๋ ์ ์ ์๊ฐ์ด ๋๋์ผ ํด์ ํ๋ ๋ฑ ๋ค์๋ ๋ฝ์ ํ๋, ๋ฐ๋ฉ์ ๋ํ ๋ก์ง์ ์ฒ ์ ํ๊ฒ ๊ตฌํํด์ผ ํ๋ค๋ ๊ฒ์ด๋ค. - ๋ค์๋ ๋ฝ์ ์ฃผ๋ก ๋ถ์ฐ ์์คํ ์์ ์ฌ๋ฌ ๋ ธ๋๊ฐ ๋์์ ์ ๊ทผํ๋ ๊ฒฝ์ฐ, ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ๊ณผ ๋์์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด ์ฌ์ฉ๋์ด์ง๋ค.
[์ธ์
1, 2 ๊ณตํต]
set tx_isolation = 'READ-UNCOMMITTED';
SET AUTOCOMMIT = FALSE;
START TRANSACTION;
[์ธ์
1]
SELECT GET_LOCK('hello', 100);
(2-4) Metadata Locks
(3) ์คํ ๋ฆฌ์ง ์์ง ๋ ๋ฒจ์ Lock
(3-1) Shared and Exclusive Locks
(3-2) Intention Locks
(3-3) Record Locks
(3-4) Gap Locks
(3-5) Next-key Locks
(3-6) Insertion Intention Locks
(3-7) Auto-INC Locks
(3-8) Predicate Locks for Spatial Indexes
[Reference]
- https://m.blog.naver.com/pjt3591oo/222479605880
- https://kdhyo98.tistory.com/101
- https://idea-sketch.tistory.com/45
- https://greeng00se.tistory.com/40
- https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html
- https://jeong-pro.tistory.com/m/239
- https://scshim.tistory.com/477
- https://velog.io/@yangsijun528/MySQL-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80-%EC%97%94%EC%A7%84
- https://cl8d.tistory.com/m/108
- https://velog.io/@fortice/MySQL-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EC%9E%A0%EA%B8%88Lock
'๐จโ๐ป Back End > MySQL' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
MySQL ์ํคํ ์ฒ - ๊ธฐ๋ณธ (0) | 2023.08.09 |
---|---|
DB Lock ๊ธฐ์ด (0) | 2023.07.30 |
ํธ๋์ญ์ ๊ฒฉ๋ฆฌ์ฑ ์์ค (0) | 2023.07.25 |
ํธ๋์ญ์ (Transaction) (0) | 2023.07.22 |
๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ ์ ์ฝ ์กฐ๊ฑด (0) | 2023.07.22 |