Example


# Hash 추가
HSET cars#a1 name 'fast car' color red year 1950
HSET cars#b1 name 'car' color red year 1960
HSET cars#c1 name 'old car' color blue year 1970
HSET cars#d1 name 'new car' color blue year 1990

FT.CREATE - 인덱스 생성


# 인덱스 생성
FT.CREATE idx:{인덱스명} ON {HASH or JSON} PREFIX {키접두어수} {...키접두어} SCHEMA {...name type}

FT.CREATE idx:cars ON HASH PREFIX 1 cars# SCHEMA name TEXT year NUMERIC color TAG


FT.SEARCH - 조회

# 조회

- 문자열 검색
FT.SEARCH idx:cars '@name:(fast car)'

- 태그 검색
FT.SEARCH idx:cars '@color:{blue}'

- 숫자 검색
FT.SEARCH idx:cars '@year:[1955 1980]'

- 다중조건
FT.SEARCH idx:cars '@name:(fast car) @color:{blue}'

FT.SEARCH - 숫자 쿼리

# 경계값 포함 
@year:[1955 1980]

# 경계값 미포함 
@year:[(1955 (1980]

# Infinite
@year:[1955 +inf]
@year:[-inf 1955]

# 범위제외
-@year:[1955 1980]

FT.SEARCH - 태그 쿼리

# 동일값
@year:{blue}

# 제외
-@year:{blue}

# 또는(or)
@year:{red|blue}

# 공백처리
@year:{light\blue}

FT.SEARCH - 텍스트 검색

* 텍스트의 경우 스테밍(어간추출)으로 정확한 값이 아니라 알고리즘을 통하여 관련 단어로 "검색"

# 전체검색
fast

#'fast' and 'car' 검색
@name:(fast car)

#'fast' or 'car' 검색
@name:(fast|car)

#'fast' not 검색
-@name:(fast)

# 오탈자 검색
@name:(%dar%) // car <- 문자 하나의 불일치 허용
@name:(%%daar%%) // car <- 두 문자의 불일치 허용
@name:(%%%daarr%%%) // car <- 세 문자의 불일치 허용

# 접두어 검색(2글자 이상)
@name:(ca*) // car

'Notes > Redis' 카테고리의 다른 글

LUA 스크립트  (0) 2025.07.24

최근 운영 중이던 서버에서 데드락으로 인해 결제가 되지 않는 이슈가 발생하였다.
트랜잭션, 데드락 등의 개념은 항상 이해했다고 생각하면서도 문제 발생 시 바로 원인과 해결법이 떠오르지 않는 개념이라 생각한다. 이번 이슈에 있었던 내용과 함께 새로이 알게 된 내용을 정리해 보려고 한다.

 

데드락은 서로 다른 트랜잭션이 있을때 각 트랜잭션에서 점유된 내용을 대기할 때 교착상태에 이르는 경우라고 할 수 있다.
임의의 테이블 ORDER 테이블이 있다고 가정하자 이때 PK 는 ORDER_ID라고 하겠다
1번 트랜잭션과 2번 트랜잭션이 아래와 같은 상황일 때 데드락은 발생한다.

-- 1번 트랜잭션: ORDER_ID = 1 인 ROW에 대한 쓰기락
UPDATE ORDER
   SET ORDER_STATE = '신규값'
 WHERE ORDER_ID = 1;

                    -- 2번 트랜잭션: ORDER_ID = 2 인 row 에 대한 쓰기락
                    UPDATE ORDER
                       SET ORDER_STATE = '신규값'
                     WHERE ORDER_ID = 2;

-- 1번 트랜잭션: ORDER_ID = 2인 ROW에 대해 접근하나 2번 트랜잭션의 락으로 인한 대기
UPDATE ORDER
   SET ORDER_STATE = '신규값'
 WHERE ORDER_ID = 2;

                    -- 2번 트랜잭션: ORDER_ID = 1인 ROW에 대해 접근하나 
                    --              1번 트랜잭션의 락으로 인한 대기
                    UPDATE ORDER
                       SET ORDER_STATE = '신규값'
                     WHERE ORDER_ID = 1;

 

위의 예시처럼 트랜잭션에서 데이터에 수정이 이루어지면 row 에 lock 이 걸리기 때문에 다른 트랜잭션은 대기하게 되고 이러한 상황이 맞물리며 트랜잭션간 교착상태에 걸릴 경우 락이 걸리게 되는것이다.

이 ORDER 테이블에 ORDER_NO라는 유니크한 값이 있다고 할 때 해당 컬럼에 유니크 키 설정이 안되어있고, 아래와 같은 상황이 발생한 것이 운영중이던 서버에서 발생했던 락 상황이다.

-- 1번 트랜잭션: ORDER_ID = 1 인 ROW에 대한 쓰기락
UPDATE ORDER
   SET ORDER_STATE = '신규값'
 WHERE ORDER_ID = 1;

                    -- 2번 트랜잭션: ORDER_ID = 2 인 row 에 대한 쓰기락
                    UPDATE ORDER
                       SET ORDER_STATE = '신규값'
                     WHERE ORDER_ID = 2;

-- 1번 트랜잭션: ORDER_NO = 1 은 ORDER_ID = 1 인 row 와 같은 하나의 row
UPDATE ORDER
   SET ORDER_STATE = '신규값'
 WHERE ORDER_NO = 1;

                    -- 2번 트랜잭션: ORDER_NO = 2는 
                    --             ORDER_ID = 2인 row와 같은 하나의 row
                    UPDATE ORDER
                       SET ORDER_STATE = '신규값'
                     WHERE ORDER_NO = 2;

 

얼핏 보면 문제 없을 것 같은 상황이다. 1번 트랜잭션은 1번 row 에만, 2번 트랜잭션은 2번 row 에만 접근하고 있기에 서로의 트랜잭션에 영향을 주지 않을 것 같이 예상된다. 당시 운영 중이던 서버에서 발생한 상황도 위와 같았음에도 불구하고 트랜잭션 락에 걸리게 된다. 락에 걸리게 된 이유는 제목에 있는 내용처럼 유니크 키를 설정할 경우에 해결되는 상황이었다.

 

락에 걸린 상황에 대해 설명해보겠다.

각 업데이트 문을 1 ~ 4번 업데이트라고 순서대로 칭하겠다.

1 ~ 2번 업데이트는 평범한 락 획득 과정이다. 3번 업데이트가 발생할 때 무슨 일이 발생할까?

우선 ORDER 테이블의 ORDER_NO = 1 인 값을 테이블에서 찾아야 할 것이다. ORDER_NO는 유니크 키가 아니므로 해당 row 를 찾기 위해 인덱스 스캔이 아닌 풀스캔이 발생할 것이다. ORDER_NO = 1 인 값을 찾기 위해 테이블 전체를 스캔하게 될 것이고 2번 트랜잭션에서 ORDER_ID = 1 인 row에 락을 걸어두었기 때문에 1번 트랜잭션은 대기에 빠지게 된다. 같은 경우로 4번 업데이트 문도 대기에 빠지게 되며 두 트랜잭션은 데드락에 걸리게 되는 것이다.

 

하지만 유니크 키를 걸게 되면 어떻게 될까?
3번 업데이트문과 4번 업데이트문은 풀스캔이 아닌 인덱스 스캔을 하게 될 것이고 해당 row 에 락을 한 것은 동일 트랜잭션이므로 스캔하는 것에 문제가 없게 되고, 두 트랜잭션은 독립적으로 처리되어 데드락 문제가 해결되게 된다.

업데이트 문을 간단히 써두었지만 실제 운영하던 서버 코드에서는 해당 원인을 찾는게 쉽지 않았다.
락이 걸린 순간의 업데이트 문과 연관된 테이블을 체크한 이후 해당 테이블에 관한 트랜잭션의 로직들을 확인하면서 의구심이 가는 부분을 확인했고, 그것이 맞았다.

 

해당 내용에 대해 실제 체크하기 위하여 임시 테이블을 만들고 사용하는 DB 툴인 DBeaver 에서 두개의 세션 스크립트를 열어두고 오토 커밋이 아닌 메뉴얼 커밋을 이용하여 테스트를 진행하였다. 그 결과 위와 같은 원인을 찾을 수 있었다.

 

인덱스, 제약 조건 등은 데이터의 신뢰성 및 DB의 성능을 위해서는 잘 처리해두어야 하지만 가끔 초기 설계 시 누락되거나, 프로젝트 진행 중에 추가된 컬럼들로 인해 올바르게 정리가 되어있지 않을 때가 존재한다. 하지만 이처럼 올바르게 정의되어지지 않은 테이블을 이와 같은 예상치 못한 문제가 발생할 가능성이 있다는 것을 다시 한 번 생각하게 되었다.

유니크 키를 설정한 해당 서버는 현재까지 데드락 이슈가 발생하지 않고 있다.

프로젝트에서 Postgresql Fdw를 이용하면서 발생했떤 성능 이슈를 해결했던 경험을 기록에 남긴다.

 

Fdw(Foreign Data Wrapper) 테이블이란?

FDW는 즉, PostgreSQL 데이터베이스 외부의 다른 데이터베이스나 파일 시스템 등에 있는 데이터를 마치 로컬 테이블처럼 접근하고 사용할 수 있게 해주는 기술이다. 외부 데이터베이스에 바로 접근 할 수 있으므로 별도의 인터페이스 정의가 필요 없이 쉽게 데이터를 공유할 수 있는 방법이다.

프로젝트 내에서 성능 문제가 발생했던 내용은 엑셀 파일 다운을 위한 데이터 조회 부분에서 발생했다. 조회해야 하는 데이터가 ERP 시스템의 Fdw 테이블과 프로젝트 테이블을 Join이 필요했다. 조회 쿼리를 완성한 이후 테스트 결과 특정 데이터의 경우 약 2분 가까이 걸리는 것을 확인했다. 최종적으로 조회 되는 데이터는 200 row 정도로 그리 많치 않음에도 시간이 많이 소요되었다.

관련해서 fdw에 대해 찾아보던 중 아래와 같은 글들을 확인했다.

 

1. Fdw Join Performance Tip

https://www.crunchydata.com/blog/performance-tips-for-postgres-fdw

 

Performance Tips for Postgres FDW | Crunchy Data Blog

Chris has some tips on helping you get the most out of queries when working with a remote Postgres foreign data wrapper. He has an overview of how queries are executed with the fdw and then samples for using CTEs, sub-queries, materialized views, and more.

www.crunchydata.com

 

2. 배민 postgres fdw 마이그레이션

https://techblog.woowahan.com/20371/

 

postgres_fdw로 마이그레이션 생산성 높이기 | 우아한형제들 기술블로그

배달의민족 커머스 서비스들의 ‘상품’ 도메인 시스템 통합 프로젝트를 하며 postgres_fdw를 이용해 PostgreSQL DB 간의 별도 배치 애플리케이션 없이 마이그레이션을 경험했던 실제 사례 및 결과와

techblog.woowahan.com

 

 

1번 링크에 대해서 요약하자면 Fdw 와의 Join 을 수행할 경우 일정량 row의 cursor 단위로 원격데이터베이스에서 데이터를 받아오기 때문에 성능이 떨어진다는 내용과 함께 바로 Join 하는 형식이 아닌 다른 방법들을 추천 해주고 있다. 내용의 핵심은 Fdw 테이블에서 조회하는 내용을 현재 데이터베이스의 공간으로 옮긴 이후 Join 을 해야 한다는 내용이다. 그렇지 않으면 Fetch Count 단위로 반복된 cursor 조회가 발생할 것이고, 이로 인행 성능이 떨어지기 때문이다.

2번 링크는 배민의 기술 블로그에서 Fdw 를 이용해서 마이그레이션시 사용한 방법에 대한 내용이다. Fdw 테이블의 데이터를 로컬테이블로 옮긴 이후에 Join 문을 수행하여 1번 링크에서 설명하는 문제점을 해결하는 내용을 확인하였다.

위 내용들을 확인하고 현재 프로젝트의 이슈를 해결해보았다. 우선 1번 링크의 소개된 내용 중 하나인 With 절의 CTE 테이블을 이용하여 일종의 로컬 메모리에 데이터를 올리는 방식을 참고했다. 그러나 어째서 인지 성능은 변화되지 않았다. 내 방식에 문제가 있었는지는 모르겠지만 With 절을 이용한 방식은 효과가 없어 2번 링크에서 보았던 부분을 참고하여 임시 테이블에 저장하는 방식을 이용해보았다.

결과는 성공적이었다. 약 2분(120초) 가까이 소요되던 쿼리 시간은 1초 이내로 줄어들었다. 성능 향상은 상당히 만족스러웠으면 Postgresql의 Fdw 가 동작하는 방식에 대해서 고민하고 알 수 있는 기회였다.

요약: Local Table 과 Fdw Table Join시 성능 이슈 발생 시, 별도의 로컬 테이블에 임시 저장한 이후 Local Table 간의 Join 으로 변경 시 성능을 향상 시킬 수 있다.

기본

-- 출력
print(123)
print('Hello World')
print("Hello World")

-- 변수 local 선언
local sumLocal = 1 + 1
print(sumLocal)

-- 변수 global 선언
sumGlobal = 2 + 2
print(sumGlobal)

-- if-then-end 
local a = 1

if a > 0 then 
    print("a 는 0보다 크다")
end

if a ~= 0 then  -- not 비교
    print("a는 0이 아니다")
end

if a == 1 then  -- 동일 비교
    print("a는 1이다")
end

if 0 and '' then 
    print("0과 빈문자열은 참이다")
end

if false or not true then
    print("이 출력문은 표시되지 않는다")
end

 

배열

-- 배열
local colors = {'red','green','blue'}

-- lua의 배열 인덱스는 "1"부터 시작
print(colors[1]) 

-- 요소의 수
print(#colors)

-- 추가
table.insert(colors, 'orange')
print(colors[4]) 
print(#colors)

-- 배열 순회
for i, v in ipairs(colors) do
    print(i, v)
end

-- 범위 순회
for i=5, 10 do 
    print(i)
end

 

테이블

-- lua table은 javascript 의 object 와 유사하다
local user = {id = 'a1', name = 'samantha'}
print(user['id'])
print(user['name'])

for k, v in pairs(user) do
    print(k, v)
end

'Notes > Redis' 카테고리의 다른 글

RedisSearch Commands  (2) 2025.08.14

토픽 생성 / 제거 / 조회


# topic 생성
kafka-topics.sh --bootstrap-server localhost:9092 --create -topic #{topic_name}
# 파티션지정 생성
kafka-topics.sh --bootstrap-server localhost:9092 --create -topic #{topic_name} 
--partitions ${partition_number}
# replication-factor 지정
kafka-topics.sh --bootstrap-server localhost:9092 --create -topic #{topic_name} 
--partitions ${partition_number} --replication-factor #{replication_number}


# topic 제거
kafka-topics.sh --bootstrap-server localhost:9092 --topic #{topic_name} --delete


# topic list 체크
kafka-topics.sh --bootstrap-server localhost:9092 --list
# topic 정보
kafka-topics.sh --bootstrap-server localhost:9092 #{topic_name} --describe

'Notes > Kafka' 카테고리의 다른 글

Kafka - WSL2 설치 및 실행  (1) 2025.06.10

3.1.0 version 기준 설치 example

# jdk 설치
sudo apt install openjdk-11jdk
java -version
javac -version

#kafka 링크 이용하여 다운로드
wget https://archive.apache.org/dist/kafka/3.1.0/kafka_2.13-3.1.0.tgz

# kafka bin 경로 체크
cd kafka_2.13-3.1.0/bin
pwd

# PATH 등록
nano .bashrc

# .bashrc 최하단 환경변수 추가
PATH="$PATH:/home/ygs/kafka_2.13-3.1.0/bin"
# 환경변수 추가 후 linux 재로그인, PATH 체크
echo $PATH 


 

Zookeeper 이용하여 실행


# 주키퍼 실행
zookeeper-server-start.sh ~/kafka_2.13-3.1.0/config/zookeeper.properties

# kafka 실행[]()
kafka-server-start.sh ~/kafka_2.13-3.1.0/config/server.properties

# kafka, zookeper 설정, kafka 로그 및 zookeper 데이터 디렉토리 설정 가능
nano kafka_2.13-3.1.0/config/zookeeper.properties
nano kafka_2.13-3.1.0/config/server.properties

 

KRaft 모드


#PATH 등록 상태에서

# 클러스터 uuid 생성
kafka-storage.sh random-uuid
# EQhLcEdZTku0cEYDOdBqxg

# storage format, 초기화
kafka-storage.sh format -t ${uuid} -c ~/kafka_2.13.3.1.0/config/kraft/server.properties

# 실행
kafka-server-start.sh ~/kafka_2.13.-3.1.0/config/kraft/server.properties

 

WSL2 네트워킹 버그 해결


# 아래 오류메시지, ipv6 문제
# Connection to node -1
# could not be stablished

# 브로커 정지후 ipv6 비활성화 필요
sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1

vi config/server.properties # or nano
# 리스너 수정 localhost:9092 example
listners=PLAINTEXT://localhost:9092



# ------------------------- 또는 아래와 같이 처리하여 ipv6 유지

sudo sysctl -w net.ipv6.conf.all.disable_ipv6=0
sudo sysctl -w net.ipv6.conf.default.disable_ipv6=0
listners=PLAINTEXT://[::1]:9092 

'Notes > Kafka' 카테고리의 다른 글

Kafka - CLI  (0) 2025.06.20

최근 프로젝트에서 Oracle 프로시저 기반의 프로젝트를 Postgresql 로 변환하는 작업을 진행하고 있다.

Aws Schema Conversion Tool를 이용하여 1차 변환 후 문제가 없는지 확인하며 추가 변환작업을 진행하는 형태로 진행하였다. 변환 작업을 하면서 많이 느꼈던 부분은 PostgreSQL의 경우 "데이터 타입"에 많은 신경을 써야한다는 것이었다.

 

변환 작업을 하면서 변환 시 체크해야 하는 상황들을 일부 정리해본다.

 
1. CURSOR 이용시 RECORD 타입 선언 필요
FOR V_RECORD IN SOME_CURSOR
LOOP
    ~~~ V_RECROD 를 이용
END LOOP;

 

위와 같은 커서 문을 작성한다고 하면
Oracle은 V_RECORD 라는 변수를 바로 참조하여 사용할 수 있지만
PostgreSQL의 경우 V_RECORD라는 변수를 DECLARE 문에 RECORD 타입으로 미리 선언해주어야 했다.

 
2. FROM DUAL

테이블의 컬럼을 바라보지 않는 Select 문 사용 시
Oracle 은 FROM DUAL 문법을 뒤에 붙여주어야 하지만
PostgreSQL 의 경우 필요하지 않았다.

 
3. 파이프라인을 이용한 문자열 합치기
# Oracle Case
SELECT 'a' || NULL || 'b' FROM DUAL; -- 결과: 'ab'

# Postgresql Case
SELECT 'a' || NULL || 'b'; -- 결과: NULL

 

파이프(||)를 이용한 문자열 합치기를 사용할 경우 Oracle 의 경우 NULL 값을 공백으로 처리하여 합쳐진다. 이는 Oracle 의 경우 공백을 NULL 로 판정하기 때문에 발생하는 결과인 것으로 예상된다.
조회 관련 쿼리에서 '%' 를 문자열의 앞뒤로 붙여 LIKE 검색을 할 경우 파이프(||)를 이용할 시 Oracle과 PostgreSQL의 결과가 완전히 달라지므로 주의해야 한다. 변환 작업 시 CONCAT_WS를 이용하였다.

 
4. 현재 날짜 및 시간

Oracle 의 경우 SYSDATE,
PostgreSQL 의 경우 NOW()를 이용하여 현재 시간을 불러올 수 있다.

 
5. 날짜 연산

Oracle 의 경우 '+', '-' 연산을 이용하여 바로 날짜 계산이 가능하지만,
Postgresql 의 아래와 같은 문법으로 타입을 명시해야한다.

# Oracle Case
SELECT SYSDATE + 1 FROM DUAL;

# Postgresql Case
SELECT NOW() + '1 days'::INTERVAL; -- INTERVAL 타입으로 연산해야한다.
 
6. 데이터 수 제한 검색 문법 및 ORDER BY 주의점

Oracle의 경우 ROWNUM 을 WHERE 절에서 비교하여 SELECT 문의 조회 건수를 제한할 수 있으며
PostgreSQL의 경우 LIMIT 문법을 이용하여 제한하여 조회할 수 있다.

이 때 ORDER BY 절이 포함된 SELECT 문이라면 변환 시 주의해야 한다.
Oracle의 ROWNUM은 ORDER BY 로 정렬되기 전에 주어지고 WHERE 절에서 제한한다면,
PosgreSQL의 LIMIT의 경우 ORDER BY 된 상태에서 LIMIT 조회가 적용되기 때문이다.
Oracle에서 PostgreSQL로 변환 시에는 인라인뷰에서 ORDER BY 하여 SELECT 문을 작성한 이후 LIMIT 를 걸어야 했다.

# Oracle Case
SELECT *
  FROM A_TABLE A
 WHERE ROWNUM <= 10;
 ORDER BY A.A_COLUMN

# PostgreSQL
SELECT *
  FROM (SELECT *
          FROM A_TABLE 
         ORDER BY A_COLUMN) A
 LIMIT 10;
 
7. Alias

Oracle 의 경우 인라인뷰에는 Alias 가 필수가 아니지만
PostgreSQL의 경우 인라인뷰에 Alias 가 필수다.

Oracle의 경우 MERGE, UPDATE, INSERT 문 등에서도 테이블에 Alias를 붙이는 것에 제한사항이 없다.
PostgeSQL의 경우 변경되는 기준이 되는 컬럼에는 Alias를 붙이면 안된다.

# Oracle Case
UPDATE A_TABE A
   SET A.A_COLUMN = 'NEW_A';Z

# PostgreSQL
# A.ACOLUMN 이런식으로 쓰면 안된다. 우항에서 값을 참조할때는 Alias 를 사용 가능하다.
UPDATE A_TABE A
   SET A_COLUMN = 'NEW_A';
 
8. 재귀 쿼리

Oracle 의 경우 CONNECT BY LEVEL 문법이 존재하여 재귀 쿼리를 짧게 작성할 수 있다.
PostgreSQL 의 경우 WITH RECURSIVE 문을 이용하여 재귀 쿼리를 작성 해야한다. Oracle에 비하여 쿼리 길이가 길어지며 가독성이 떨어진다고 느꼈다. 쿼리 작성 난이도도 상승한다.

 
9. SELECT 'STRICT' INTO

Oracle 에서 변수에 값을 담기 위하여 SELECT INTO 문법 사용 시 조회 되는 값이 없을 경우 NO DATA EXCEPTION 이 발생한다.
PostgreSQL의 경우 SELECT INTO 문법 사용 시 조회 되는 값이 없어도 EXCEPTION이 발생하지 않는다.

Oracle -> PostgreSQL 변환 시 Oracle과 같은 형태로 Exception 발생을 위해선 SELECT INTO STRICT를 사용하여야 한다.

 
10. Mybatis 관련

Spring Mybatis 에서 Function 을 호출하여 CURSOR 결과를 리턴 받을 시 jdbcType 설정
Oracle의 경우 "CURSOR" 타입으로 설정한 후 CALL 값을 등호로 받는다.
PostgreSQL의 경우 "OTHER" 타입으로 설정한 후 Function의 추가 파라미터로 넣은 후 CALL 한다.

 
11. 프로시져 실행 시 CASE WHEN 문의 오류 검사

변환 작업 시 CASE WHEN 문을 이용하여 잘못된 결과일 경우 1/0 값을 결과로 하여 강제로 오류를 발생 시키는 로직이 있었다.

Oracle 의 경우 실제 CASE WHEN 문에서 조건에 해당할 경우 DIVISION BY ZERO 오류가 발생하여 원하는 대로 컨트롤 할 수 있지만.
PostgreSQL의 경우 CASE WHEN 조건에 걸리지 않더라도 바로 DIVISION BY ZERO가 발생하였다. 아마도 PostgreSQL 에선 CASE WHEN 문의 결과 값을 미리 체크하는 형태로 동작하는 것으로 생각되었다. 하지만 1/0의 값을 CASE WHEN 문에 바로 작성하지 않고 별도의 Function 에서 리턴하는 형태로 작성할 경우 오류가 발생하지 않고 조건에 걸리는 경우에만 발생하였다. 따라서 기존 Oracle 프로그램과 같은 형태로 변환하기 위하여 DIVISION BY ZERO 를 리턴할 수 있는 별도의 Function으로 처리하기로 하였다.

 

 

12. ROW 위치를 지정하는 논리적 주소 값

Oracle의 경우 Row 마다 위치를 지정하는 물리적 주소 값 ROWID 가 존재한다. UPDATE 시에도 변하지 않는다.
PostgreSQL의 경우 Row 마다 위치를 지정하는 물리적 주소 값 CTID 가 존재한다. UPDATE 시에는 값이 변한다.

Oracle 에서 UPDATE 로직이 있는 ROWID 와 관련된 값을 PosgreSQL로 변환하기 위해선 별도의 Unique 값을 채번해서 사용하여야 한다. 만약 UPDATE 가 없는 경우라면 CTID 값으로 변환하여 적용하여도 문제는 없을 것으로 판단된다.

# 스프링 로그파일 시간기준 검색
awk '$0 >= "2025-01-06 14:00:00" && $0 <= "2025-01-06 15:00:00"' /path/to/logfile.log

'Notes > Linux' 카테고리의 다른 글

터미널 텍스트 이동, 편집 관련 단축키  (0) 2024.07.03

+ Recent posts