Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 데이터베이스 오류
- #데이터베이스 #트랜잭션 #ACID #격리수준
- django slack
- 정렬
- ssl.key
- AWS Aurora
- private.pem
- #백준 #드래곤커브 #알고리즘
- 비즈니스적 관점에서 생각하는 개발자 #개발자 마인드
- slack bot
- django #django 5.0 #django 5.0 요약
- public.pem
- innodb_buffer_pool_size 오류
- 업비트 웹소켓
- 개발자와 비즈니스
- 비즈니스적 관점에서 생각하는 개발자
- 개발자에세이
- sed명령어
- django 슬랙봇
- 숲을 바라보는 개발자
- 개발자와 비즈니스 관계
- add colume
- 개발자의 마인드
- 웹소켓 api
- 알고리즘
- MySQL
- django slack bot
- #알고리즘
- 슬랙봇
- 비즈니스
Archives
- Today
- Total
Info-Tech
sed 명령어를 통한 mysql table add colume 하기! 본문
문제상황
약 3gb가 넘는 table에 새로운 컬럼을 하나 추가해야하는 상황이었다. (대략 4억 이상의 데이터 값들이 들어있음)
첫번째.
처음에는 아무생각없이 아래와 같은 방법으로 컬럼을 추가해봤다.
alter table ~~ add new_colume after ~~
도저히 끝날 기미가 보이지 않고, 실제 운영중인 서비스이기 때문에 최대한 lock (downtime)이 걸리면 안되었다.
두번째.
갓 스택오버플로우의 검색결과
abc라는 테이블에 컬럼을 추가한다고 했을 때, abc_v2 테이블을 하나 만들고 여기다가 colume 추가 후 abc의 값들을 abc_v2로 옮기는 방법이다.
30분씩 50만개씩 쉬지않고 data를 옮긴다고 가정했을 때, 4억 / 50만개 = 24000분 => 400시간 => 16.6일 이상의 걸리는 신밧드의 모험을 경험 할 수 있다.
마지막.
위에서 하는 방법은 시간이 너무 오래걸려, 서비스에 지장이 갈 수 있다. 그렇다면 만들어 둔 abc_v2를 활용하면서 더 빠르게 작업할 수 있는 방법은 있을까?
물론 있다.
흔히 우리가 mysqldump를 통한 백업을 많이 진행한다.
즉 mysql dump과정에서 백업할 때 필요한 정보들이 저장이된다. (create문, insert문 등등)
이러한 원리를 이용해보자.
컬럼을 추가하고 싶은 db의 table을 백업 받고 (abc 테이블) , 그 백업된(sql 확장자로 저장된) 파일의 메타정보를 수정하면 어떨까?
mysqldump --opt --user=root--p! --lock-tables=false --single-transaction --no-create-info --order-by-primary --complete-insert db_name abc > abc.sql
이렇게 백업을 받는다.
lock-table false로 지정, single-transation을 지정한 이유는 downtime없이 (lock없이) 서비스가 실행되고 싶기 때문이다.
--no-create-info : create table 안해주기 위해 지정,
--complete-insert : INSERT INTO `abc_v2` (`id`, `price_btc`, `is_approx`, `coin_id`, `timestamp`) 형식을 맞추기 위해 지정 => 이걸 하는 이유는 abc와는 달리 abc_v2에 새로운 컬럼을 추가했음으로, table 구조가 변했기 때문이다.
이런식으로 sql를 백업한다.
다음 리눅스에 내장되어 있는 sed 명령어를 활용하여 진행해봤다.
ed명령어와 grep명령어 기능의 일부를 합친 것이 sed(stream editor)명령어이다.
라인들을 하나씩 읽고 , 수정하고, 출력하기 때문에 기억장치 안의
버퍼를 사용하지 않는다는 것이다. 버퍼를 사용하지 않으면 파일의 크기에 제한 없이 작업을 할 수 있다.
ed와 같이 버퍼를 사용하는 경우는 버퍼의 크기보다 큰 파일은 처리할 수 없으며 대개 버퍼의 크기는
1MB정도이다. 따라서 sed는 아주 큰 화일을 처리할 때 주로 사용된다.
저장된 abc.sql 파일을 한번 sed 명령어를 통해 살펴보자.
sed -n ‘1,10p’ abc.sql
실행결과
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Dumping data for table `abc`
--
실행결과 dumping된 table의 이름은 abc이렇게 나온다.
이 메타정보들을 abc_v2로 인식이 되게하여, 테이블 복원시 abc_v2 테이블에 데이터가 지정되도록 바꿔주면 된다.
즉 이번에도 sed 명령어를 통해 메타정보를 바꾸자.
sed -i ’s/abc/abc_v2/g’ abc.sql
생각보다 간단하다. 위의 명령은 abc의 텍스쳐를 abc_v2로 모두 변경하는 명령이다.
데이터가 클 수록 5분이상 걸릴 수도 있다.
변경 후
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Dumping data for table `abc_v2`
--
이로써 abc의 테이블의 이름은 abc_v2로 바뀌었고, 기존 abc의 값들을 abc_v2로 밀어 넣어주기만 하면 끝이 난다.
mysql -u root -p db_name < abc.sql
'데이터베이스' 카테고리의 다른 글
Mysql 5.6 설치 및 세팅 [우분투] (0) | 2019.03.19 |
---|
Comments