본문 바로가기

PostgreSQL

(PostgreSQL) JSON VS JSONB RDB에 JSON 포맷을 저장할 때, 평소처럼 텍스트 포맷으로 저장할지, JSON Format을 적용할지 고민하게 된다. 뫼비우스의 띠 같은 삶을 사는 나는 딱 1년전에도 비슷한 고민을 했었다.( 작년에 조사한 글 : 👉 [MariaDB]RDB 속에서 NOSQL 사용하기 👈)작년에는 리서치만 해보고 말았는데, 올해에는 PostgreSQL에 JSON 타입을 실제로 적용해봐야겠다. 🐜🐜🐜고럼 이만 포스팅 시작~ ㅎ.ㅎ PostgreSQL의 JSON 타입은 크게 2가지이다. JSON, JSONB 두가지 유형이다. JSON Type은 9.4 버전부터 추가되었다. 공통점둘다 JSON 포맷 유효성체크를 한다. 차이점데이터 저장 방식JSON은 들어온 그대로 값을 저장한다. 그런데 JSONB는 그대로 저장하지 않는다...
(PostgreSQL) Transaction과 Lock에 대한 이모저모 Table Lock Mode Table Lock Mode에 따라 공존할 수 있는 Lock이 있고, Conflict나는 Lock이 있다. SELECT를 막는 Table Lock은 ACCESS EXCLUSIVE 뿐이다. Lock Mode의 최종보스다. SELECT FOR SHARE는 FOR UDPATE, FOR SHARE 쿼리에서 필요하다. EXCLUSIVE는 UDPATE / DELETE 등의 쿼리에서 필요하다. EXCLUSIVE Lock 모드는 서로 충돌난다. 그래서 동일한 Row를 여러 트랜잭션에서 동시에 업데이트할 수 없는거다. SHARE UPDATE EXCLUSIVE는 Vacuum, 인덱스 추가 등의 쿼리에서 필요하다. Transaction과 Lock Blocking 트랜잭션이 느린 경우, Lock ..
(PostgreSQL) DB Lock을 줄이는 7가지 팁 해당 글은 When Postgres blocks: 7 tips for dealing with locks을 보고 정리한 글입니다 1. Default 값이 있는 필드를 추가하면 안된다 PostgreSQL 10버전 이하를 쓰고 있다면, Default 값이 있는 필드를 추가하면, 테이블 락이 걸릴 수 있다. 그리고 엄청 느리다. 그래서 이런 쿼리를 날리면 안된다. ALTER TABLE items ADD COLUMN updated_at timestamptz DEFAULT now();기본값이 없는 필드를 추가한 후, UPDATE를 날리거나 ALTER TABLE items ADD COLUMN updated_at timestamptz; UPDATE items SET updated_at = now();이렇게 쪼개서, U..
(PotgreSQL) ROW SHARE Lock이란? ROW SHARE Lock이란? Table Level Lock의 일종이다. Row라는 이름이 들어간다고 Row Lock이 아니다. SELECT FOR UPDATE, SELECT FOR SHARE 명령문을 날릴 때, 대상이 되는 테이블에 락을 잡는다. UPDATE, DELETE 명령문을 날릴 때, RowShareLock이 잡히는 경우도 있다. UPDATE / DELETE 명령문을 날릴 때, RowShareLock이 잡히는 케이스는 다음과 같다. aurthor의 id를 참조하고 있는 content 테이블이 있다고 가정해보자. CREATE TABLE authors ( id serial NOT NULL PRIMARY KEY, name text NOT NULL ); CREATE TABLE contents ( id..
(Django) Django ORM에서 Row Lock 잡기 - select_for_update Row Lock과 SELECT * FOR UPDATE UPDATE / DELETE 없이, SELECT 만으로 Row Lock을 잡고 싶을 때는, "SELECT * FOR UPDATE" 쿼리를 사용하면 된다. 이렇게 Row Lock을 잡고있는 도중에는 다른 트랜잭션에서 해당 Row를 변경 / 삭제할 수 없다. select_for_update Django에서 SELECT * FOR UPDATE 쿼리를 사용할 때는, Django ORM select_for_update 함수를 사용하면 된다. 이 함수는 항상 transaction과 함께 사용된다. Lock을 잡으려는데, 이미 Lock이 잡혀있는 경우 일반적으로는, 락이 풀릴 때까지 기다린다. ( 이 경우, DB Connection이 무한정 쌓이고 밀릴 수 있다...
(PostgreSQL) 슬로우쿼리를 잡아내는 3가지 방법 해당 글은 Weekly Postgres에서 보내준 3 WAYS TO DETECT SLOW QUERIES IN POSTGRESQL을 보고 정리한 글입니다 😀 슬로우쿼리를 잡아내는 3가지 방법PostgreSQL에서 슬로우쿼리를 잡아내는 방법은 크게 3가지가 있다.1. 슬로우 쿼리가 발생하면 로그 남기기2. 쿼리 실행계획 로그에 남기기3. 쿼리 실행 통계 보기 1. 슬로우 쿼리가 발생하면 로그 남기기어느정도 느려지면, 쿼리 실행문을 로그에 남길건지 postgresql.conf에 설정값을 추가해줘야한다.1log_min_duration_statement = 5000 그리고 config를 reload 해주면 된다.12345postgres=# SELECT pg_reload_conf(); pg_reload_conf -..
(PostgreSQL) Default 값이 있는 새로운 필드 추가하기 Default 값이 있는 새로운 필드 추가하기ALTER TABLE orders ADD COLUMN price bigint NOT NULL DEFAULT 0; PostgreSQL 10 이하 버전에서는 테이블에 Default 값이 있는 필드를 추가할 땐 주의해야한다. Default값이 있는 필드를 추가할 때, 테이블을 다시 만들어내기 때문이다!그러면 시간도 오래걸리고, ACCESS EXCLUSIVE LOCK도 잡게 된다. ( 참고 - Fast Column Creation with Defaults )ACCESS EXCLUSIVE LOCK이 걸려있는 동안, 이 테이블에 대한 모든 트랜잭션은 BLOCK된다! SELECT 쿼리까지 막힌다! ( ACCESS EXCLUSIVE LOCK LEVEL은 LOCK LEVEL ..
(PostgreSQL)Idle in transaction 프로세스 자동으로 죽이기 문제 상황postgresql에서 transaction이 잡혀있지만, 아무것도 하지 않으면, 세션의 상태는 idle in transaction이 된다. 그런데 얘가 connection은 쥐고 있지만, 아무것도 안한다면 서버 자원을 잘 활용하지 못하게 된다. ( 참고 - (Django)PostgreSQL의 Idle In Transaction Connection )그러면 connection이 무한대로 늘어난다거나, connection이 필요한애가 DB를 제대로 활용하지 못하게 될 수 있다. 해결 방법postgresql에는 Idle in transaction이 일정 기간동안 유지되면 자동으로 이 transaction을 죽여주는 기능이 있다. idle_in_transaction_session_timeout 옵션을..