INSERT INTO SELECT SHARED LOCK(row LOCK)
ํ
์คํธ 1
๋ชฉํ
Table๋จ์์ LOCK
์ด ๊ฑธ๋ฆฌ๋๊ฐ? ์๋๋ฉดROW๋จ์์ LOCK
์ด ๊ฑธ๋ฆฌ๋๊ฐ? (๋ ์ฝ๋ ๋ฝ)ROW๋จ์
: ํน์ ๋ฐ์ดํฐ์๋งSHARED LOCK
์ด ๊ฑธ๋ฆฌ๊ณ , ๋ค๋ฅธ๋ฐ์ดํฐ์CRUD
์๋ ์ํฅ์ด ์๋๊ฐ?SHARED LOCK
: ์ฝ๊ธฐ ๊ฐ๋ฅ. ์์ /์ญ์ ๋ถ๊ฐ
์๋๋ฆฌ์ค
Transaction Mode: Manual
create table test1 (
col1 int primary key auto_increment,
col2 char(10)
);
create table test2 select * from test1 limit 0;
insert into test1 (col2) values ('aaa'),('bbb'),('ccc');
## ํ์ฌ ๊ฑธ๋ฆฐ lock ์กฐํ
select * from performance_schema.data_locks
1. Session 1
col1=1
S๋ฝ ํ๋ ์๋primaryKey=1
S๋ฝ ํ๋ ์ฑ๊ณต
begin;
insert into test2
select *
from test1
where col1 = '1';

2. Session 2
col1=2
X๋ฝ ํ๋ ์๋primaryKey=2
X๋ฝ ํ๋ ์ฑ๊ณต
update test1
set col2 = '1111'
where col1 = 2;

3. Session 2
col1=1
X๋ฝ ํ๋ ์๋ํ์ง๋ง Session 1 ์์ S๋ฝ์ ๊ฑธ๊ณ ์๊ธฐ์ ํธํ๋์ง ์์ WAITING.
update test1
set col2 = '1111'
where col1 = 1;

4. Session 1 commit, Session 2 commit
๊ฒฐ๊ณผ
๋ฝ์ด ๊ฑธ๋ฆฌ์ง ์์ ๋ ์ฝ๋์๋ update๊ฐ ๊ฐ๋ฅํ๋ค.
S๋ฝ์ด ๊ฑธ๋ฆฐ ๋ ์ฝ๋์ X๋ฝ์ด ๋ค์ด์ค๋ฉด S๋ฝ์ด ํด์ ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฐ๋ค.
S๋ฝ๊ณผ X๋ฝ์ ํธํ๋์ง ์๋๋ค.
timeout์ ์ฃผ๋ฒ.
์ฆ InnoDB๋ ๋ ์ฝ๋๋ฝ์ผ๋ก ์์ง์ธ๋ค.
ํ์ง๋ง..
์ ๋ฆฌํ๋ฉด์ ์ต๊ทผ ์ฝ์ REAL MySQL์ ์ ๊ธ ํํธ๊ฐ ์๊ฐ๋์ ๋ค์ ์ฝ์ด๋ดค์ต๋๋ค.
์ด ํ
์ด๋ธ์ ์ธ๋ฑ์ค๊ฐ ํ๋๋ ์๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
์ด๋ฌํ ๊ฒฝ์ฐ์๋ ํ
์ด๋ธ์ ํ ์ค์บํ๋ฉด์ UPDATE ์์
์ํ๋๋ฐ,
์ด ๊ณผ์ ์์ ํ
์ด๋ธ์ ์๋ 30์ฌ๋ง ๊ฑด์ ๋ชจ๋ ๋ ์ฝ๋๋ฅผ ์ ๊ทธ๊ฒ ๋๋ค.
์ด๊ฒ์ด MySQL์ ๋ฐฉ์์ด๋ฉฐ, MySQL์์ ์ธ๋ฑ์ค ์ค๊ณ๊ฐ ์ค์ํ ์ด์ ๋ํ ์ด๊ฒ์ด๋ค.
- REAL MySQL 1๊ถ. 5.3.2 ์ธ๋ฑ์ค์ ์ ๊ธ (172p)
์ด ๋ด์ฉ์ ์ฝ๊ณ ์์ ํ ์คํธ๋ฅผ ๋ค์ ๋ณด๋
where ์กฐ๊ฑด์ col1์ PK์ด๊ธฐ์ unique index๋ก ์ด๋ฏธ ์กํ์์ด ๋จ์ผ ๋ ์ฝ๋๋ฝ์ด ๊ฑธ๋ฆฝ๋๋ค.
ํ์ง๋ง index๊ฐ ์๋ col2๋ผ๋ฉด?
col2์ non unique index๋ฅผ ๊ฑธ๊ณ ์กฐํํ๋ค๋ฉด?
ํ
์คํธ 2
๋ชฉํ
index๊ฐ ์๋ col2๋ฅผ where ์กฐ๊ฑด์ผ๋ก ์คํํ๋ ๊ฒฝ์ฐ ๋ ์ฝ๋๋ฝ์ด ์ด๋ป๊ฒ ์กํ๋๊ฐ?
์๋๋ฆฌ์ค
์ด๊ธฐ ์ธํ ๋
1. Session 1
col2=bbb
S๋ฝ ํ๋ ์๋.ํ์ง๋ง ๋ชจ๋ ๋ ์ฝ๋์ ๋ํด S๋ฝ ํ๋ ์ฑ๊ณต.
begin;
insert into test2
select *
from test1
where col2 = 'bbb';

2. Session 2
col2=ccc
X๋ฝ ํ๋ ์๋.ํ์ง๋ง Session 1 ์์ ๋ชจ๋ ๋ ์ฝ๋์ S๋ฝ์ ๊ฑธ๊ณ ์๊ธฐ์ ํธํ๋์ง ์์ WAITING.
update test1
set col2 = 'fff'
where col2 = 'ccc';

3. Session 1 commit, Session 2 commit
๊ฒฐ๊ณผ
index๊ฐ ์๋ค๋ฉด ๋ชจ๋ ๋ ์ฝ๋๊ฐ ๋ฝ์ ๊ฑธ๋ฆฐ๋ค.
ํ
์คํธ 3
๋ชฉํ
col2์ non unique index๋ฅผ ๊ฑธ๊ณ where ์กฐ๊ฑด์ผ๋ก ์คํํ๋ ๊ฒฝ์ฐ ๋ ์ฝ๋๋ฝ์ด ์ด๋ป๊ฒ ์กํ๋๊ฐ?
์๋๋ฆฌ์ค
create table test1
(
col1 int primary key auto_increment,
col2 char(10)
);
create table test2
select *
from test1
limit 0;
insert into test1 (col2)
values ('aaa'), ('aaa'),
('bbb'), ('bbb'),
('ccc'), ('ccc');
create index test1_col2_index on test1(col2); ## ์ธ๋ฑ์ค ์์ฑ
1. Session 1
col2=bbb
S๋ฝ ํ๋ ์๋primaryKey=3,4,5
S๋ฝ ํ๋ ์ฑ๊ณตcol2๋ non unique index ์ด์ง๋ง
primaryKey=3,4
S๋ฝ ํ๋ ์ฑ๊ณต.primaryKey=5
๋ S๋ฝ์ด์ GAP๋ฝ์ผ๋ก ํ๋ํ๋๋ฐ ์ด๋ถ๋ถ์ ์ข ๋ ๊ณต๋ถํด์ผ๋ฉ๋๋ค.
begin;
insert into test2
select *
from test1
where col2 = 'bbb';

2. Session 2
col2=ccc
X๋ฝ ํ๋ ์๋primaryKey=5,6
X๋ฝ ํ๋ ์ฑ๊ณต๊ทผ๋ฐ unique index์ด๋ ๊ฒ๊ณผ ๋ค๋ฅด๊ฒ REC_NOT_GAP, GAP ๋ฝ๋ค์ด ์ถ๊ฐ๋ก ํ๋๋ฉ๋๋ค.
update test1
set col2 = 'fff'
where col2 = 'ccc';

3. Session 2
col2=bbb
X๋ฝ ํ๋ ์๋ํ์ง๋ง Session 1 ์์ S๋ฝ์ ๊ฑธ๊ณ ์๊ธฐ์ ํธํ๋์ง ์์ WAITING.
update test1
set col2 = 'ggg'
where col2 = 'bbb';

4. Session 1 commit, Session 2 commit
๊ฒฐ๊ณผ
ํ ์คํธ 1๊ณผ ๊ฒฐ๊ณผ๋ ๊ฐ์ง๋ง ๋ฝ์ด ๊ฑธ๋ฆฌ๋ ํํ๊ฐ ๋งค์ฐ ๋ค๋ฆ ๋๋ค.
์ต์ข
๊ฒฐ๋ก
innoDB์์ unique index์ ๋ํ INSERT INTO SELECT SHARED LOCK
๋ ๋ ์ฝ๋ ๋ฝ์ด ๋ง์ต๋๋ค.
INSERT INTO SELECT SHARED LOCK
๋ ๋ ์ฝ๋ ๋ฝ์ด ๋ง์ต๋๋ค.ํ์ง๋ง non unique index์ ๊ฒฝ์ฐ ๋ฝ์ด ๊ฑธ๋ฆฌ๋ ํํ๊ฐ ๋งค์ฐ ๋ค๋ฆ ๋๋ค.
IS, IX, ๊ฐญ ๋ฝ๋ฑ์ ๋ํ ๊ณต๋ถ๊ฐ ๋ถ์กฑํด ์ ํํ ์ด๋ค ์ฐจ์ด๊ฐ ์๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
์ฌ์ง์ด no index ์ธ ๊ฒฝ์ฐ๋ ์ ์ฒด ๋ ์ฝ๋ ๋ฝ์ผ๋ก ํ ์ด๋ธ ๋ฝ๊ณผ ๊ฐ์ ์ํ๊ฐ ๋ฉ๋๋ค.
ํ์ง๋ง ์ค๋ฌด์์๋ ํฐ ๋ฌธ์ ๊ฐ ์์ ๊ฒ์ผ๋ก ์์๋ฉ๋๋ค.
์ด ์ด์๋ ์ผ๋ฐ์ ์ด์ง ์์ ์ ๋ฌด ํ๋ฆ์์ ์๊ธฐ ์์ ๊ฐ ํธ๋์ญ์ ์กฐ์์ ์๋ชปํ ์ธ์ ์ค์๊ฐ ๋ ํฝ๋๋ค. (์์ ์ ์์ฒญ)
์ค๋ฌด์์ ์ฌ์ฉ๋๋ ํ ์ด๋ธ์ ์ต์ํ non unique index๊ฐ ๊ฑธ๋ ค ์์ ๊ฒ์ ๋๋ค.
Last updated
Was this helpful?