> For the complete documentation index, see [llms.txt](https://docs.tibero.com/tmaxopensql/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tibero.com/tmaxopensql/tmax-openproxy/openproxy.md).

# Openproxy 사용 설명서

## OpenProxy 사용 설명서

> 버전: 1.1.3

***

### 1. Synopsis

```
openproxy [config_file]
openproxy show [--full] [--format toml|json] [--section <섹션명>]
openproxy edit [--set <key>=<value>]
openproxy encode [password]
openproxy --force-config-file [config_file]
openproxy [--log-target file|stdout|both] [--log-level trace|debug|info|warn|error]
          [--log-dir <디렉토리>] [--max-logfile-num <개수>] [--log-format text|structured|debug]
openproxy --version
openproxy --help
```

***

### 2. 개요

OpenProxy는 Rust로 작성된 PostgreSQL 커넥션 풀러 및 프록시입니다. 애플리케이션은 OpenProxy를 PostgreSQL 서버처럼 연결하며, OpenProxy가 실제 서버 연결을 관리합니다.

**주요 기능**

* **커넥션 풀링**: 새 연결 생성 비용을 줄여 성능을 개선합니다.
* **읽기/쓰기 분리**: 쿼리를 자동으로 분석하여 쓰기는 primary, 읽기는 replica로 라우팅합니다.
* **로드 밸런싱**: 여러 replica 간에 읽기 쿼리를 분산합니다.
* **자동 Failover**: OpenSQL 에서 primary가 변경되면 자동으로 감지하여 새 primary로 연결합니다.
* **etcd 연동**: etcd에 설정을 저장하고 여러 OpenProxy 인스턴스 간에 설정을 공유합니다.
* **VRRP / VIP**: 여러 OpenProxy 인스턴스 앞단에 가상 IP를 제공하여 고가용성을 구성합니다.

***

### 3. 핵심 개념

#### 3.1 커넥션 풀링 모드

OpenProxy는 두 가지 풀링 모드를 지원합니다.

**트랜잭션 풀링 (transaction)** — 권장

트랜잭션이 시작될 때 서버 연결을 할당하고, 트랜잭션이 끝나면 즉시 풀로 반환합니다. 하나의 서버 연결을 여러 클라이언트가 순차적으로 재사용하므로 연결 수를 크게 줄일 수 있습니다.

> 단, 트랜잭션 외부에서 SET 명령어나 임시 테이블을 사용하는 경우 의도하지 않은 동작이 발생할 수 있습니다.

**세션 풀링 (session)**

클라이언트가 연결된 동안 서버 연결이 전용으로 유지됩니다. SET 명령, 준비된 구문, 임시 테이블 등 세션 상태를 사용하는 애플리케이션에 적합합니다. 단, 서버 연결 수 절감 효과가 트랜잭션 풀링에 비해 작습니다.

#### 3.2 읽기/쓰기 분리 (Query Router)

`query_parser_enabled = true`와 `query_parser_read_write_splitting = true`를 설정하면 OpenProxy가 SQL 쿼리를 파싱하여 자동으로 역할을 결정합니다.

* `SELECT` → replica로 라우팅
* `INSERT`, `UPDATE`, `DELETE`, DDL → primary로 라우팅
* 트랜잭션 내부 쿼리 → 트랜잭션 시작 시점에 결정된 역할 유지

`primary_reads_enabled = true`로 설정하면 replica가 없거나 부하 분산이 필요한 경우 primary도 읽기 대상에 포함됩니다.

#### 3.3 운영 모드

OpenProxy는 두 가지 운영 모드를 지원합니다.

**파일 단독 모드**

설정 파일(`openproxy.toml`)만 사용합니다. 설정 파일이 변경되면 5초 주기로 자동 감지하여 reload합니다. 단일 서버 환경이나 etcd 없이 운영하는 경우에 적합합니다.

**etcd 연동 모드 (HA)**

설정을 etcd에 저장하고 여러 노드가 공유합니다. etcd의 설정이 변경되면 모든 OpenProxy 인스턴스에 자동으로 반영됩니다. Patroni와 동일한 etcd 클러스터를 사용하여 primary/replica 역할을 자동으로 감지합니다.

#### 3.4 설정 우선순위

설정이 여러 곳에 있을 경우 다음 우선순위를 따릅니다.

```
CLI 플래그 > etcd > 설정 파일
```

`--force-config-file` 옵션을 사용하면 etcd를 무시하고 설정 파일만 사용합니다.

#### 3.5 VRRP / VIP

여러 OpenProxy 인스턴스를 운영할 때 클라이언트가 항상 활성 인스턴스에 연결할 수 있도록 가상 IP(VIP)를 제공합니다. VRRP 프로토콜을 사용하여 인스턴스 간에 VIP 소유권을 협상하며, 활성 인스턴스가 다운되면 다른 인스턴스가 VIP를 인수합니다.

VRRP 기능을 사용하려면 `CAP_NET_ADMIN`, `CAP_NET_RAW` 권한이 필요합니다. OpenSQL 에서 제공하는 systemd 서비스 파일을 사용하면 해당 권한이 자동으로 부여됩니다.

***

### 4. 빠른 시작

#### 파일 단독 모드

1. 설정 파일을 작성합니다.

```toml
[general]
host = "0.0.0.0"
port = 6432
admin_username = "admin"
admin_password = "adminpassword"

[pools.mydb]
pool_mode = "transaction"
auth_type = "scram-sha-256"

[pools.mydb.users.0]
username = "appuser"
password = "apppassword"
server_username = "appuser"
server_password = "apppassword"
pool_size = 20

[pools.mydb.shards.0]
servers = [
    ["192.168.1.10", 5432, "primary"],
    ["192.168.1.11", 5432, "replica"],
]
database = "mydb"
```

2. OpenProxy를 실행합니다.

```bash
openproxy /etc/openproxy/openproxy.toml
```

3. 접속을 확인합니다.

```bash
psql -h 127.0.0.1 -p 6432 -U user mydb
```

#### etcd 연동 모드 (HA)

1. 설정 파일에 etcd 섹션을 추가합니다.

```toml
[general]
host = "0.0.0.0"
port = 6432
admin_username = "admin"
admin_password = "adminpassword"

[general.etcd]
enabled = true
endpoints = ["192.168.1.1:2379", "192.168.1.2:2379", "192.168.1.3:2379"]
patroni_namespace = "/service"
patroni_scope = "opensql"

[pools.mydb]
pool_mode = "transaction"
auth_type = "scram-sha-256"
query_parser_enabled = true
query_parser_read_write_splitting = true

[pools.mydb.users.0]
username = "appuser"
password = "apppassword"
server_username = "appuser"
server_password = "apppassword"
pool_size = 20

[pools.mydb.shards.0]
servers = [
    ["192.168.1.10", 5432, "Auto"],
    ["192.168.1.11", 5432, "Auto"],
    ["192.168.1.12", 5432, "Auto"],
]
database = "mydb"
use_patroni = true
```

2. OpenProxy를 실행합니다.

```bash
openproxy /etc/openproxy/openproxy.toml
```

etcd에 연결되면 설정이 etcd에 저장되고 이후부터는 etcd를 통해 관리됩니다.

***

### 5. systemd 서비스 등록

운영 환경에서는 systemd 서비스로 등록하여 실행하는 것을 권장합니다. 서버 재부팅 시 자동으로 시작되고, 비정상 종료 시 자동으로 재시작됩니다.

**서비스 파일 위치**: `/etc/systemd/system/openproxy.service`

```ini
[Unit]
Description=OpenProxy - PostgreSQL Connection Pooler (OpenSQL)
After=network.target etcd.service
StartLimitIntervalSec=0

[Service]
User=opensql
Type=simple
Restart=always
RestartSec=5
Environment=RUST_LOG=info
ExecStart=/usr/bin/openproxy /etc/openproxy/openproxy.toml
StandardOutput=journal
StandardError=journal
SyslogIdentifier=openproxy
LimitNOFILE=65536
# VRRP 사용 시 필요. VRRP 미사용 시 제거 가능.
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW

[Install]
WantedBy=multi-user.target
```

**서비스 등록 및 시작**

```bash
# 서비스 파일 복사 후 daemon reload
sudo systemctl daemon-reload

# 부팅 시 자동 시작 활성화
sudo systemctl enable openproxy

# 서비스 시작
sudo systemctl start openproxy

# 상태 확인
sudo systemctl status openproxy

# 로그 확인
sudo journalctl -u openproxy -f
```

**서비스 중지 및 재시작**

```bash
sudo systemctl stop openproxy
sudo systemctl restart openproxy
```

***

### 6. 실행 옵션

#### `openproxy [config_file]`

OpenProxy를 시작합니다. `config_file`을 지정하지 않으면 현재 디렉토리의 `openproxy.toml`을 사용합니다.

```bash
openproxy
openproxy /etc/openproxy/openproxy.toml
```

#### `openproxy show`

현재 로드된 설정을 출력하고 종료합니다. 서비스를 시작하지 않습니다.

```bash
# 기본 (TOML 형식, 명시적으로 설정된 항목만)
openproxy show

# 기본값 포함 전체 설정 출력
openproxy show --full

# JSON 형식으로 출력
openproxy show --format json

# 특정 섹션만 출력
openproxy show --section general
openproxy show --section pools.mydb
```

설정 파일 경로를 지정하는 경우, 경로는 반드시 서브커맨드 앞에 위치해야 합니다.

```bash
# OK: config_file이 서브커맨드 앞에 위치
openproxy /etc/openproxy/openproxy.toml show

# Fail: config_file이 서브커맨드 뒤에 오면 인식되지 않음
openproxy show /etc/openproxy/openproxy.toml
```

#### `openproxy edit`

설정을 편집하고 저장합니다.

```bash
# 대화형: $EDITOR로 설정 파일 열기
openproxy edit

# 비대화형: 특정 값 변경
openproxy edit --set general.pool_size=20
openproxy edit --set general.connect_timeout=2000

# 여러 값 동시 변경
openproxy edit --set general.connect_timeout=2000 --set general.idle_timeout=300000
```

설정 파일 경로를 지정하는 경우, 경로는 반드시 서브커맨드 앞에 위치해야 합니다.

```bash
# OK: config_file이 서브커맨드 앞에 위치
openproxy /etc/openproxy/openproxy.toml edit --set general.pool_size=20

# Fail: config_file이 서브커맨드 뒤에 오면 인식되지 않음
openproxy edit /etc/openproxy/openproxy.toml --set general.pool_size=20
```

etcd가 활성화된 경우, 변경 내용은 etcd에 저장되며 설정 파일은 수정되지 않습니다. 단, `virtual_router` 설정은 etcd에 저장되지 않으므로 설정 파일에서 직접 수정해야 합니다.

#### `openproxy encode`

데이터베이스 사용자 비밀번호를 SCRAM-SHA-256 서버에서 인식할 수 있는 형태로 암호화합니다.

```bash
openproxy encode 'mypassword!@#'
```

출력되는 결과값은 `openproxy.toml` 파일의 사용자 Password로 사용할 수 있습니다. `auth_type` 값이 `scram-sha-256` 형태로 지정된 경우에만 올바르게 동작합니다.

PostgreSQL에 연결하기 위한 `server_password` 값으로는 사용할 수 없습니다.

```
[pools.my_pool]
auth_type = "scram-sha-256"

[pools.my_pool.users.0]
username = "opensql_user"
password = "SCRAM-SHA-256$4096:..."
```

#### `--force-config-file`

etcd가 활성화된 환경에서도 설정 파일만 사용합니다. etcd 연결 문제 발생 시 임시 우회 수단으로 사용합니다.

```bash
openproxy --force-config-file /etc/openproxy/openproxy.toml
```

#### 로그 옵션

<table><thead><tr><th width="221">옵션</th><th width="136">기본값</th><th>설명</th></tr></thead><tbody><tr><td><code>--log-target</code></td><td><code>both</code></td><td>로그 출력 대상. <code>file</code> (파일만), <code>stdout</code> (표준출력만), <code>both</code> (둘 다)</td></tr><tr><td><code>--log-level</code></td><td><code>info</code></td><td>로그 레벨. <code>trace</code>, <code>debug</code>, <code>info</code>, <code>warn</code>, <code>error</code></td></tr><tr><td><code>--log-dir</code></td><td><code>logs</code></td><td>로그 파일 저장 디렉토리. <code>log-target</code>이 <code>file</code> 또는 <code>both</code>일 때 사용</td></tr><tr><td><code>--max-logfile-num</code></td><td><code>5</code></td><td>로그 파일 최대 보관 개수. 로그 파일은 매일 자정에 새로 생성되며, 보관 개수 초과 시 오래된 파일부터 삭제</td></tr><tr><td><code>--log-format</code></td><td><code>text</code></td><td>로그 출력 형식. <code>text</code> (사람이 읽기 쉬운 형식), <code>structured</code> (JSON 등 구조화 형식), <code>debug</code></td></tr></tbody></table>

```bash
# 로그를 파일로만 저장, 저장 경로 및 보관 개수 지정
openproxy --log-target file --log-dir /var/log/openproxy --max-logfile-num 10 /etc/openproxy/openproxy.toml

# 로그 레벨을 debug로 설정하여 표준출력으로만 출력
openproxy --log-target stdout --log-level debug /etc/openproxy/openproxy.toml
```

***

### 7. 관리자 콘솔

OpenProxy는 관리자 콘솔을 제공합니다. PostgreSQL 클라이언트로 `openproxy` 데이터베이스에 접속하여 사용합니다.

#### 접속 방법

```bash
psql -h 127.0.0.1 -p 6432 -U <admin_username> openproxy
```

`admin_username`과 `admin_password`는 설정 파일의 `general.admin_username`, `general.admin_password`에 정의된 값입니다.

#### SHOW 명령어

<table><thead><tr><th width="261">명령어</th><th>설명</th></tr></thead><tbody><tr><td><code>SHOW POOLS</code></td><td>각 풀의 커넥션 수, 대기 클라이언트 수 등 풀 상태</td></tr><tr><td><code>SHOW CLIENTS</code></td><td>현재 연결된 클라이언트 목록</td></tr><tr><td><code>SHOW SERVERS</code></td><td>현재 열려 있는 서버 연결 목록</td></tr><tr><td><code>SHOW STATS</code></td><td>쿼리 수, 바이트 수, 응답 시간 등 통계</td></tr><tr><td><code>SHOW DATABASES</code></td><td>설정된 풀(데이터베이스) 목록</td></tr><tr><td><code>SHOW USERS</code></td><td>설정된 사용자 목록</td></tr><tr><td><code>SHOW CONFIG</code></td><td>현재 로드된 설정 값</td></tr><tr><td><code>SHOW LISTS</code></td><td>내부 오브젝트 개수 통계</td></tr><tr><td><code>SHOW BANS</code></td><td>일시 차단된 서버 목록</td></tr><tr><td><code>SHOW VERSION</code></td><td>OpenProxy 버전 정보</td></tr><tr><td><code>SHOW HELP</code></td><td>사용 가능한 명령어 목록</td></tr></tbody></table>

#### 제어 명령어

<table><thead><tr><th width="249">명령어</th><th>설명</th></tr></thead><tbody><tr><td><code>RELOAD</code></td><td>설정을 다시 로드합니다. etcd 활성 시 Patroni 역할만 갱신합니다.</td></tr><tr><td><code>PAUSE [db, user]</code></td><td>지정한 풀(또는 전체)의 새 쿼리 수신을 중지합니다. 진행 중인 트랜잭션은 완료를 기다립니다.</td></tr><tr><td><code>RESUME [db, user]</code></td><td>PAUSE로 중지된 풀을 재개합니다.</td></tr><tr><td><code>SHUTDOWN</code></td><td>OpenProxy를 종료합니다.</td></tr></tbody></table>

#### SET 명령어

```sql
SET key = value
```

일부 설정 값을 런타임에 변경합니다.

***

### 8. 제약사항

#### etcd.enabled 변경 시 프로세스 재시작 필요

`general.etcd.enabled` 값을 `false`에서 `true`로, 또는 `true`에서 `false`로 변경하는 경우 **반드시 OpenProxy 프로세스를 재시작해야 합니다.**

파일 기반 설정 자동 reload가 변경을 감지하더라도, etcd watch 태스크는 프로세스 시작 시 최초 1회만 활성화됩니다. 런타임 중 `enabled` 값을 변경해도 etcd 연동이 활성화되거나 비활성화되지 않습니다.

```bash
# 설정 파일에서 enabled 변경 후 반드시 재시작
sudo systemctl restart openproxy
```

#### etcd 활성 시 RELOAD 동작 차이

etcd가 활성화된 상태(`enabled = true`)에서 `RELOAD` 명령 또는 `SIGHUP` 시그널을 보내면 설정 전체를 재로드하는 대신 **Patroni 역할 정보만 갱신**합니다.

etcd 연동 환경에서 설정을 변경하려면 `openproxy edit` 명령을 사용하거나 etcd에 직접 값을 저장해야 합니다.

#### virtual\_router는 etcd 동기화 대상에서 제외

`[general.virtual_router]` 설정은 노드마다 다를 수 있으므로(interface 이름, priority 등) etcd에 저장되지 않습니다. 해당 설정은 각 노드의 설정 파일에서 직접 관리해야 합니다.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.tibero.com/tmaxopensql/tmax-openproxy/openproxy.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
