mojh7 / real-mysql-study

:orange_book: Real MySQL 8.0 study
0 stars 0 forks source link

2023/03/28 ~ 2023/04/03 #48

Open mojh7 opened 1 year ago

mojh7 commented 1 year ago

다음 스터디

2023-04-03 pm 10:10 월요일

정리 범위

  1. 11.7.4.3 ~ 11.7.4.5
  2. 11.7.4.6 ~ 11.7.5 전부
github-actions[bot] commented 1 year ago

정리 범위 무작위 선택 봇 🔎

  1. 장현
  2. 단비
danbi5228 commented 1 year ago

11.7.4.6 테이블 구조 복사

11.7.4.7 테이블 삭제

11.7.5 칼럼 변경

11.7.5.1 칼럼 추가

11.7.5.2 칼럼 삭제

11.7.5.3 칼럼 이름 및 칼럼 타입 변경


-- 칼럼 이름 변경. 리빌드가 필요하지 않아 INSTNAT 알고리즘과 같이 빠르게 완료됨
-- 칼럼 to_date 를 end_date로 이름 변경
ALTER TABLE salaries CHANGE to_date end_date DATE NOT NULL,
    ALGORITHM=INPLACE, LOCK=NONE;

-- INT 칼럼을 VARCHAR 타입으로 변경. 칼럼 타입이 변경되는 경우 COPY 알고리즘이 필요하고 변경 중에 쓰기 작업은 불가
ALTER TABLE salaries MODIFY salary VARCHAR(20),
    ALGORITHM=COPY, LOCK=SHARED;

-- VARCHAR 타입의 길이 확장. 길이 변경되기 전 후 저장 공간의 차이에 따라 리빌드가 필요여부가 갈리게 됨
-- 예제의 경우 10에서 20으로 변경해도 칼럼 값이 최대 가질 수 있는 바이트 수의 변함이 없으므로 테이블 리빌드가 필요 없음
ALTER TABLE salaries MODIFY salary VARCHAR(20),
    ALGORITHM=INPLACE, LOCK=NONE;

-- VARCHAR 타입의 길이 축소. 완전히 다른 타입으로 변경되는 경우와 동일하게 COPY 알고리즘이 필요하고 변경 중 쓰기 작업 불가
ALTER TABLE salaries MODIFY salary VARCHAR(10),
    ALGORITHM=COPY, LOCK=SHARED;
mojh7 commented 1 year ago

11.7.4.3 테이블 구조 변경

ALTER TABLE 명령어 사용

테이블 자체에 대한 속성 변경은 주로 문자 집합이나 스토리지 엔진, 파티션 구조 등의 번겅

ALTER TABLE employees
  CONVERT TO CHARACTER SET UTF8MB4 COLLATE UTF8MB4_GENERAL_CI,
  ALGORITHM=INPLACE, LOCK=NONE;

ALTER TABLE employees ENGINE=InnoDB
ALGORITHM=INPLACE, LOCK=NONE;

테이블 스토리지 엔진을 변경하는 명령은 내부적인 테이블의 저장소를 변경하는 것이라서 항상 테이블의 모든 레코드를 복사하는 작업이 필요하다

실제 테이블의 스토리지 엔진을 변경하는 목적으로도 사용되지만 테이블 데이터를 리빌드하는 목적으로도 사용


테이블이 사용하는 디스크 공간의 프래그멘테이션을 최소화하고, 테이블의 구조를 최적화하기 위한 OPTIMIZE TALBE이라는 명령이 있는데 내부적으로 ALTER TALBE ... ENGINE=InnoDB 명령과 동일한 작업을 수행함


11.7.4.4 테이블 명 변경

RENAME TABLE table1 TO table2;
RENAME TABLE db1.table1 TO db2.table2;

첫 번째 명령에서 단순히 테이블의 이름만 변경하는 작업은 메타 정보만 변경하기 때문에 빠르게 처리됨

두 번째 명령에서는 다른 DB로 테이블을 이동할 수 있는데, 메타 정보뿐만 아니라 테이블이 저장된 파일까지 다른 디렉터리로 이동해야한다


db1와 db2가 서로 다른 파티션에 만들어졌다고 가정하면 테이블을 db1에서 db2로 이동할 때

데이터 파일의 복사 작업이 필요하기 때문에 데이터 파일의 크기에 비례해서 시간이 소요될 것이다

일반적으로 유닉스나 윈도우에서 서로 다른 파티션으로 파일을 이동할 때

MySQL서버의 RENAME TABLE에서도 똑같이 작동한다


일정 주기로 테이블을 교체해야 할 때

RENAME TABLE batch TO batch_old
RENAME TABLE batch_new TO batch

다음과 같이 테이블을 교체할텐데 신규 테이블을 교체하는 동안 일시적으로 batch 테이블이 없어지는 시점이 발생해서 에러가 발생할 수 있다

이런 문제점을 막기 위해 RENAME 명령을 하나의 문장으로 묶어서 실행할 수 있다

RENAME TABLE batch TO batch_old
             batch_new TO batch;

여러 테이블의 RENAME 명령을 하나의 문장으로 묶으면

명시된 모든 테이블에 대해 잠금을 걸고 테이블의 이름 변경 작업을 실행한다

응용 프로그램 입장에서 batch 테이블을 조회하려고 하면 잠금이 걸려있기 때문에 대기하고 RENAME TABLE 명령이 완료되면 batch 테이블의 잠금이 해제되어 batch_new 였던 테이블을 읽게된다

잠깐의 잠금 대기가 발생할 뿐 에러가 발생하지는 않는다


11.7.4.5 테이블 상태 조회

MySQL의 모든 테이블은 다음과 같은 정보를 가진다

데이터 파일의 버전, 레코드 포맷 등과 같이 자주 사용되지는 않지만 중요한 정보도 가지고 있는데

SHOW TABLE STATUS ... 로 조회하면 된다

SHOW TABLE STATUS ... 으로 출력되는 내용에서 레코드 건수나 평균 크기는 MySQL 서버가 예측하고 있는 값이기에 테이블이 너무 작거나 크면 오차가 더 커질 수도 있다

다음과 같이 SELECT 쿼리를 이용해 조회할 수도 있다

SELECT * FROM information_schema.TABLES
WHERE TABLE_SCHEMA='employees' AND TABLE_NAM='employees' \G

infomation_schema DB는