[etc] Nginx Origin URI into proxy pass

톰켓 proxypass 시에 header 에 Original URI 전달하기.

헤더값에 original URI 정보 입력하는  테스트 ..


톰켓과 같은 어플리케이션 서버 앞에 일반적으로 nginx 를 이용한 리저브 프록시 형태의 서비스를 이용하는데 있어, 
다음과 같이 커스텀한 헤더나 혹은 Extend 헤더를 추가함으로 was에서 들어오는 request 에 대한 형태를 판단 할 수 있습니다.


관련해서 proxy backend   넘겨줄  X-Original-URI 말고 X-forwarded-URI 로도 넘겨주는 방법(동일?) 선택하면 될듯합니다.

nginx 설정

header  X-Original-URI

location / {
proxy_set_header X-Original-URI $request_uri;
            proxy_pass http://127.0.0.1:8080/;
        }


         location /testuri/ {
          proxy_set_header X-Original-URI $request_uri;
            proxy_pass http://127.0.0.1:8080/;
        }

테스트를 위해 nginx 의 로케이션이 상이한 두개의 경우에도 동일하게 톰켓의 루트 ( / ) 로 프록시 되도록 설정을 해두었다. 
위와 같은 경우 was 의 access 로그를 확인하게 되면 웹서버의 "/$uri" 및 "/testuri/$uri" 는 동일하게 패싱된다. 

이런 경우 실제 nginx로 포함되는 request_uri를 프록시 과정에 X-Origin-URI 헤더로 셋업하여 전달해준다. 

이후 java 설정에서 아래와 같이 헤더정보를 가져오게 되면 

request.getHeader("X-Original-URI");  

실제로 들어오는 요청에 대한 값을 판단 할 수 있게된다.


실제 패킷 분석 시 헤더 결과 

(톰켓으로 넘어가는 loopback 8080 캡쳐 : # tcpdump i lo qexX port 8080)

get http://test.hongstalk.com/ 

09:54:56.618161 00:00:00:00:00:00 (oui Ethernet) > 00:00:00:00:00:00 (oui Ethernet), IPv4, length 623: localhost.47502 > localhost.webcache: tcp 557

        0x0000:  4500 0261 210a 4000 4006 198b 7f00 0001  E..a!.@.@.......

        0x0010:  7f00 0001 b98e 1f90 7f44 b41a 86a9 4ace  .........D....J.

        0x0020:  8018 0200 0056 0000 0101 080a 4fc9 9511  .....V......O...

        0x0030:  4fc9 9511 4745 5420 2f20 4854 5450 2f31  O...GET./.HTTP/1

        0x0040:  2e30 0d0a 582d 4f72 6967 696e 616c 2d55  .0..X-Original-U

        0x0050:  5249 3a20 2f0d 0a48 6f73 743a 2031 3237  RI:./..Host:.127



get http://test.hongstalk.com/testuri

09:58:54.909510 00:00:00:00:00:00 (oui Ethernet) > 00:00:00:00:00:00 (oui Ethernet), IPv4, length 543: localhost.47504 > localhost.webcache: tcp 477

        0x0000:  4500 0211 f02b 4000 4006 4ab9 7f00 0001  E....+@.@.J.....

        0x0010:  7f00 0001 b990 1f90 59d0 c7ce 9d52 e649  ........Y....R.I

        0x0020:  8018 0200 0006 0000 0101 080a 4fcd 37e4  ............O.7.

        0x0030:  4fcd 37e4 4745 5420 2f20 4854 5450 2f31  O.7.GET./.HTTP/1

        0x0040:  2e30 0d0a 582d 4f72 6967 696e 616c 2d55  .0..X-Original-U

        0x0050:  5249 3a20 2f74 6573 7475 7269 0d0a 486f  RI:./testuri..Ho

테스트 과정에서 볼 수 있듯이, 루프백 어뎁터를 통해 실제 톰켓 으로 GET 을 통해서 / 에대한 요청이 들어오는건 두 요청이 모두 동일하지만,  X-origin-URI 헤더를 추가함으로써, 실제 웹 서버로 어떤 request 를 통해 접근하는지를 판단 할 수 있다.

[etc] 자주 사용하는 redis cli command 정리

SCAN 0 COUNT 100 MATCH *

# 100개 제한 읽어오기. Keys * 보다 효율적임..

 

DEBUG OBJECT 키

# 해당 정보의 사이즈 lru , expire 정보등을 읽어옴

 

SETEX 키 시간 키밸류

# expire time을 걸어 아이템을 set 한다.

# setex hong 60 sungho 라고 입력하면, 60초간 hong이라는 키가 저장된다.

 

 

SLOWLOG GET

# get 으로 시작하는 카운트 중 시간이 오개걸리는 값을 반환한다..

# 일반적으로 겟 명령어에서 슬로우 로그가 발생하는 경우 해당 키값의 데이터가 용량이 가장 큰 (메모리를 많이 잡아먹는) 키 값이다..

# 레디스 운영 시 OOM redis Out Of Memory 같은 경우, 해당 키 또는 리스트의 값이 너무 큰 (보통 팝 과정 없이  잘못 쌓이는 push LIST에서 발생한다. )

# GET , RESET, LEN  등을 확인 할 수 있다.

 

Lpush, Lpop, Rpush , Rpop

# push 는 데이터를 입력하며, Left, Right로 데이터를 입력한다.

# pop 은 데이터를 읽는 개념이 아닌, 가져간다는 표현으로 pop을 통해 꺼내어진 데이터는 해당 데이터테이블에서 삭제된다.

# Lrange 명령을 통해서 대상이 지정된 범위의 리스트를 읽어온다. 0 은 시작점을 의미하고, -1 은 리스트의 끝 (오른쪽 마지막) 을 의미하므로, 모든 리스트에 저장된 데이터를 확인 할 때 사용한다.

# 모든 리스트에서 데이터를 꺼내어 쓰면, 데이터가 없다는 의미의 nil 을 표시한다.

# 예시 )

Rpush hong A B C

 

LRANGE hong 0 -1

“A”

“B”

“C”

 

Rpop hong

“C”

 

Rpop hong

“B”

 

Rpop hong

“A”

 

Rpop hong

(nil)

 

 

Redis-cli -h HOSTNAME –stat

# 레디스의 key count, memory Usage, clinet, blocked, requests, connections 정보를 알려줌..

 

Redis-cli -h HOSTNAME -c ‘keys hong*” | xargs redis-cli -h HOSTNAME DEL

# hong으로 시작하는 모든 키를 검색하여, 한번에 지우는 방법..

[etc] URL encode & decode

browser 에서 문자열이 encode 되어 들어가는 명칭에 대한 부분입니다.

추후에도 찾기 쉽게 정리해둡니다.

html 등의 소스에서 잘못된 값이 들어가는 경우 (주로 스페이스) 등이 발생하는 경우 확인하기 편리합니다~

참고로 아래 사이트에서는 실제 인코드&디코드 결과를 바로 확인 가능하니 즐겨찾기 등을 해두시면 수월합니다.

http://www.url-encode-decode.com/

 

Character From Windows-1252 From UTF-8
space %20 %20
! %21 %21
%22 %22
# %23 %23
$ %24 %24
% %25 %25
& %26 %26
%27 %27
( %28 %28
) %29 %29
* %2A %2A
+ %2B %2B
, %2C %2C
%2D %2D
. %2E %2E
/ %2F %2F
0 %30 %30
1 %31 %31
2 %32 %32
3 %33 %33
4 %34 %34
5 %35 %35
6 %36 %36
7 %37 %37
8 %38 %38
9 %39 %39
: %3A %3A
; %3B %3B
< %3C %3C
= %3D %3D
> %3E %3E
? %3F %3F
@ %40 %40
A %41 %41
B %42 %42
C %43 %43
D %44 %44
E %45 %45
F %46 %46
G %47 %47
H %48 %48
I %49 %49
J %4A %4A
K %4B %4B
L %4C %4C
M %4D %4D
N %4E %4E
O %4F %4F
P %50 %50
Q %51 %51
R %52 %52
S %53 %53
T %54 %54
U %55 %55
V %56 %56
W %57 %57
X %58 %58
Y %59 %59
Z %5A %5A
[ %5B %5B
\ %5C %5C
] %5D %5D
^ %5E %5E
_ %5F %5F
` %60 %60
a %61 %61
b %62 %62
c %63 %63
d %64 %64
e %65 %65
f %66 %66
g %67 %67
h %68 %68
i %69 %69
j %6A %6A
k %6B %6B
l %6C %6C
m %6D %6D
n %6E %6E
o %6F %6F
p %70 %70
q %71 %71
r %72 %72
s %73 %73
t %74 %74
u %75 %75
v %76 %76
w %77 %77
x %78 %78
y %79 %79
z %7A %7A
{ %7B %7B
| %7C %7C
} %7D %7D
~ %7E %7E
%7F %7F
` %80 %E2%82%AC
 %81 %81
%82 %E2%80%9A
ƒ %83 %C6%92
%84 %E2%80%9E
%85 %E2%80%A6
%86 %E2%80%A0
%87 %E2%80%A1
ˆ %88 %CB%86
%89 %E2%80%B0
Š %8A %C5%A0
%8B %E2%80%B9
Π%8C %C5%92
 %8D %C5%8D
Ž %8E %C5%BD
 %8F %8F
 %90 %C2%90
%91 %E2%80%98
%92 %E2%80%99
%93 %E2%80%9C
%94 %E2%80%9D
%95 %E2%80%A2
%96 %E2%80%93
%97 %E2%80%94
˜ %98 %CB%9C
%99 %E2%84
š %9A %C5%A1
%9B %E2%80
œ %9C %C5%93
 %9D %9D
ž %9E %C5%BE
Ÿ %9F %C5%B8
%A0 %C2%A0
¡ %A1 %C2%A1
¢ %A2 %C2%A2
£ %A3 %C2%A3
¤ %A4 %C2%A4
¥ %A5 %C2%A5
¦ %A6 %C2%A6
§ %A7 %C2%A7
¨ %A8 %C2%A8
© %A9 %C2%A9
ª %AA %C2%AA
« %AB %C2%AB
¬ %AC %C2%AC
%AD %C2%AD
® %AE %C2%AE
¯ %AF %C2%AF
° %B0 %C2%B0
± %B1 %C2%B1
² %B2 %C2%B2
³ %B3 %C2%B3
´ %B4 %C2%B4
µ %B5 %C2%B5
%B6 %C2%B6
· %B7 %C2%B7
¸ %B8 %C2%B8
¹ %B9 %C2%B9
º %BA %C2%BA
» %BB %C2%BB
¼ %BC %C2%BC
½ %BD %C2%BD
¾ %BE %C2%BE
¿ %BF %C2%BF
À %C0 %C3%80
Á %C1 %C3%81
 %C2 %C3%82
à %C3 %C3%83
Ä %C4 %C3%84
Å %C5 %C3%85
Æ %C6 %C3%86
Ç %C7 %C3%87
È %C8 %C3%88
É %C9 %C3%89
Ê %CA %C3%8A
Ë %CB %C3%8B
Ì %CC %C3%8C
Í %CD %C3%8D
Î %CE %C3%8E
Ï %CF %C3%8F
Ð %D0 %C3%90
Ñ %D1 %C3%91
Ò %D2 %C3%92
Ó %D3 %C3%93
Ô %D4 %C3%94
Õ %D5 %C3%95
Ö %D6 %C3%96
× %D7 %C3%97
Ø %D8 %C3%98
Ù %D9 %C3%99
Ú %DA %C3%9A
Û %DB %C3%9B
Ü %DC %C3%9C
Ý %DD %C3%9D
Þ %DE %C3%9E
ß %DF %C3%9F
à %E0 %C3%A0
á %E1 %C3%A1
â %E2 %C3%A2
ã %E3 %C3%A3
ä %E4 %C3%A4
å %E5 %C3%A5
æ %E6 %C3%A6
ç %E7 %C3%A7
è %E8 %C3%A8
é %E9 %C3%A9
ê %EA %C3%AA
ë %EB %C3%AB
ì %EC %C3%AC
í %ED %C3%AD
î %EE %C3%AE
ï %EF %C3%AF
ð %F0 %C3%B0
ñ %F1 %C3%B1
ò %F2 %C3%B2
ó %F3 %C3%B3
ô %F4 %C3%B4
õ %F5 %C3%B5
ö %F6 %C3%B6
÷ %F7 %C3%B7
ø %F8 %C3%B8
ù %F9 %C3%B9
ú %FA %C3%BA
û %FB %C3%BB
ü %FC %C3%BC
ý %FD %C3%BD
þ %FE %C3%BE
ÿ %FF %C3%BF

[etc] ElasticSearch – cloud-aws Plugin

엘라스틱 서치 운영에 있어, 클러스터링 할 노드들에 대한 ping & discover 관련하여 매우 유용한 플러그인이 존재합니다.

기존 기 배포된 인스턴스에 올리는 형태가 아닌 자동화를 생각하신다면 해당 플러그인이 매우 유용하게 사용될 것입니다.

제 경우는 Ansible이란 툴을 이용해서 배포 및 형상관리를 진행하고 있는데요,

아래와 같은 방법을 통해서 클라우드 환경에 클러스터 노드를 구축합니다.

아래는 샘플입니다.

<pre><code>

# {{ ansible_managed }}

cluster.name: 클러스터명

node.name: {{ ansible_hostname }}

node.master: true

node.data: true

network.host: 0.0.0.0

bootstrap.mlockall: true

discovery.zen.ping_interval: 5s

discovery.zen.ping_timeout: 30s

discovery.zen.ping_retries: 3

# cloud-aws by hong

plugin.mandatory: “cloud-aws”

cloud.aws.region: “ap-northeast-1”

cloud.aws.access_key: “액세스키”

cloud.aws.secret_key: “시크릿키”

discovery.zen.ping.multicast.enabled: false

discovery.type: “ec2”

discovery.ec2.groups: “시큐리티그룹명”

discovery.ec2.host_type: “private_ip”

discovery.ec2.ping_timeout: “30s”

discovery.ec2.availability_zones: [“ap-northeast-1a”, “ap-northeast-1c”]

</code></pre>

 

위의 설정중 눈여겨 볼 부분은 # 주석의 cloud-aws 부분입니다.

해당 기능을 사용하는데 있어, 백업 & 리스토어 기능을 사용하기 위해서는 s3 권한을

자동 디스커버 관련 권한은 ec2-describe관련 권한이 필요합니다.

해당 IAM 키를 생성하실때 아래와 같은 폴리시를 이용하시면 됩니다.

{

“Version”: “2012-10-17”,

“Statement”: [

{

“Effect”: “Allow”,

“Action”: “s3:*”,

“Resource”: [

“arn:aws:s3:::버킷명”,

“arn:aws:s3:::버킷명/*”

]

},

{

“Effect”: “Allow”,

“Action”: “EC2:Describe*”,

“Resource”: “*”

}

]

}

 

해당 기능을 이용하여 ElasticSearch 데이터를 백업 복구 할 수 있으며 S3를 이용하기에 리전간 마이그레이션에도 이용할 수 있습니다.

주목할 만한 점은, discover옵션 중 discover.ec2.groups 지시자를 통해 동일한 Security Group을 사용하는 인스턴스에 discover가 가능하기 때문에, 고정된 아이피를 사용하지 않는 환경에서도 적절히 사용할 수 있다는 점입니다.

 

추가 옵션 설정등은 추후 정리하도록 하겠습니다~

 

 

[linux] jq 1.5 release – build RPM

jq 란 ?

lightweight and flexible command-line JSON processor.

api 호출등에 데이터를 주고받는데 있어, 최근 json포멧을 사용하는 경우가 많습니다.

커멘드라인을 이용해서 curl등의 도구를 이용해서 데이터를 가져오는 경우 해당 데이터를 json 포멧등으로 (일반적으로 pretty form) 변환 하거나 sed, awk , grep 등 다양한 데이터 파싱이 가능한 도구입니다.

 

최근 …(이래도 2015년 8월 15일) 1.5버전이 릴리즈 되어 있으니, 이걸 RPM 으로 빌드하고, 사용해봅시다.

 

 

https://stedolan.github.io/jq/download/

최신버전 1.5를 빌드 하기 위해 해당 사이트를 방문하여 최신버전의 소스 파일을 다운 받습니다.

 

wget https://github.com/stedolan/jq/releases/download/jq-1.5/jq-1.5.tar.gz

 

SPEC 생성

빌드뤼카이어, valgrind 설치

1.5 버전 에서   bison 3.0이하의 버전에서는 아래와 같이 컨피그 옵션을 수정합니다.
빌드 하는 환경은 cent6 이므로, 2.7 버전이 설치되어 있습니다.

./configure –disable-maintainer-mode

 

추가로 make check 가 진행될 때 setup.sh 에서 참조하는 것중

PASS: tests/mantestPASS: tests/jqtestFAIL: tests/onigtestPASS: tests/shtest

 

위에 onigtest 가 실패하는 것은  테스트 작업 설정시 oniguruma.h 를 참조하기 때문인데요.

이는 setup.sh를 수정하여 리패키징 하거나, oniguruma-devel 패키지를 설치하여, 해당 해더를 위치시킨후 처리가능합니다.

 

또한 1.5서 추가되는 라이브러리 패스가 추가되어 https://github.com/stedolan/jq/blob/master/jq.spec 처럼 %{_libdir} 을 추가할 필요가 있습니다.

 

 

rpm 명세서.

Name:           jq

Version:        1.5

Release:        1%{?dist}

Summary:        Command-line JSON processor

License:        MIT and ASL 2.0 and CC-BY and GPLv3

URL:            http://stedolan.github.io/jq/

Source0:        http://stedolan.github.io/%{name}/download/source/%{name}-%{version}.tar.gz

BuildRequires:  flex

BuildRequires:  bison

%ifarch %{ix86} x86_64

BuildRequires:  valgrind

%endif

%description

lightweight and flexible command-line JSON processor

 jq is like sed for JSON data – you can use it to slice

 and filter and map and transform structured data with

 the same ease that sed, awk, grep and friends let you

 play with text.

 It is written in portable C, and it has zero runtime

 dependencies.

 jq can mangle the data format that you have into the

 one that you want with very little effort, and the

 program to do so is often shorter and simpler than

 you'd expect.

%prep

%setup -qn %{name}-%{version}

%build

%configure --disable-maintainer-mode

make %{?_smp_mflags}

# Docs already shipped in jq's tarball.

# In order to build the manual page, it

# is necessary to install rake, rubygem-ronn

# and do the following steps:

#

# # yum install rake rubygem-ronn

# $ cd docs/

# $ curl -L https://get.rvm.io | bash -s stable --ruby=1.9.3

# $ source $HOME/.rvm/scripts/rvm

# $ bundle install

# $ cd ..

# $ ./configure

# $ make real_docs

%install

make DESTDIR=%{buildroot} install

%check

# Valgrind used, so restrict architectures for check

%ifarch %{ix86} x86_64

make check

%endif

%files

%{_bindir}/%{name}

%{_datadir}/man/man1/jq.1.gz

%{_datadir}/doc/jq/AUTHORS

%{_datadir}/doc/jq/COPYING

%{_datadir}/doc/jq/README

%{_datadir}/doc/jq/README.md

%{_includedir}/jq.h

%{_includedir}/jv.h

%{_libdir}/libjq.a

%{_libdir}/libjq.la

%{_libdir}/libjq.so

%{_libdir}/libjq.so.1

%{_libdir}/libjq.so.1.0.4

%changelog

* Wed Nov 30 2016 Sungho Hong <nic2hong@jinstalk.com> - 1.5-1

- Initial package release for 1.5 jq.

[aws] 호스트 네임 Resolve (reverse resolving hostname) 이슈

VPC 존에 사용중인 인스턴스에 자동으로 할당되는 호스트 명

예시 (ip-10-10-10-10) 의 경우, 해당 도메인을 이용해 서로간에 ip를 리졸빙할 수 있어야하는 경우가 많다.

 

아마존의 경우는 해당 부분은 VPC에서 설정할 수 있으며, 아래와 같이 설정 가능하다.

capture_1027_002

 

 

 

다음은 해당 내용에 대한 사항이다.

http://docs.aws.amazon.com/ko_kr/AmazonVPC/latest/UserGuide/vpc-dns.html

콘솔을 사용하여 VPC에 대한 DNS 지원을 설명하고 업데이트하려면

  1. https://console.aws.amazon.com/vpc/에서 Amazon VPC 콘솔을 엽니다.
  2. 탐색 창에서 [Your VPCs]를 선택합니다.
  3. 목록에서 VPC를 선택합니다.
  4. [Summary] 탭의 정보를 검토합니다. 이 예제에서는 두 가지 모두 사용합니다.
    DNS 설정 탭

 

[기타] 루트 도메인 네임 서버 정보

Root DNS 13개인줄 아세용?

 

DNS 프로토콜의 응답 패킷인 UDP (사용자 데이터그램 프로토콜) 내 수용 가능한 서버 수의 최대치가 13대 이기때문에 전 세계에서 오직 13대의 대형 컴퓨터에만 루트 DNS가 존재합니다.

 

참고로, 미국은 10개, 2대는 노르웨이, 네덜란드, 아시아에선 유일하게 일본에 root DNS 가 있습니다.

 

 

UDP 수용 가능 서버 최대치가 13 일까요?

 

Root DNS 가 13대가 넘어가면 DNS 질의 시 사용되는 메시지 사이즈가 512바이트를 넘어가게 됩니다. DNS는 UDP를 사용하지만 512바이트를 넘어가면 TCP로 재 질의 하도록 되어 있습니다.

Root 에서부터 재 질의가 많이 일어나는 경우 부하로 인해 서비스에 영향을 주게 됩니다.

 

 

참고 :

 

[root@ip-10-28-74-156 gamesvr]# dig . ns

 

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.10.rc1.el6_3.2 <<>> . ns

;; global options: +cmd

;; Got answer:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55690

;; flags: qr rd ra; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 0

 

;; QUESTION SECTION:

;.                              IN      NS

 

;; ANSWER SECTION: # ROOT DNS

.                       87243   IN      NS      e.root-servers.net.

.                       87243   IN      NS      f.root-servers.net.

.                       87243   IN      NS      g.root-servers.net.

.                       87243   IN      NS      h.root-servers.net.

.                       87243   IN      NS      i.root-servers.net.

.                       87243   IN      NS      j.root-servers.net.

.                       87243   IN      NS      k.root-servers.net.

.                       87243   IN      NS      l.root-servers.net.

.                       87243   IN      NS      m.root-servers.net.

.                       87243   IN      NS      a.root-servers.net.

.                       87243   IN      NS      b.root-servers.net.

.                       87243   IN      NS      c.root-servers.net.

.                       87243   IN      NS      d.root-servers.net.

 

;; Query time: 9 msec

;; SERVER: 172.16.0.23#53(172.16.0.23)

;; WHEN: Wed Jun  5 08:46:07 2013

;; MSG SIZE  rcvd: 228 # 욘석이 바로 메시지 사이즈

[기타] TCP 상태 관련 정리

 

 

TCP 연결상태

 

 

TCP 연결 단계 (RFC 793)

 

TCP A                                                                                              TCP B

  1. CLOSED                                            LISTEN
  2. SYN-SENT –> < SEQ=100>< CTL=SYN>                                   –>  SYN-RECEIVED
  3. ESTABLISHED <– < SEQ=300>< ACK=101>< CTL=SYN,ACK> <–    SYN-RECEIVED
  4. ESTABLISHED –> < SEQ=101>< ACK=301>< CTL=ACK> –>  ESTABLISHED
  5. ESTABLISHED –> < SEQ=101>< ACK=301>< CTL=ACK>< DATA> –>  ESTABLISHED

 

LISTEN       : 데몬이 요청을 발을 수 있도록 연결 요구를 기다리는 상태.

즉, http(80), mail(25), ftp(21), telnet(23) 등의 포트가 열려있음을 의미.

윈도우즈에서는 LISTENING으로 표시.

SYN_SENT : 로컬에서 원격으로 연결 요청(SYN 신호를 보냄)을 시도한 상태.

SYN_RECV : 원격으로 부터 연결 요청을 받은 상태.

요청을 받아 SYN+ACK 신호로 응답은 한 상태이지만 ACK는 받지 못했다.

netstat로 확인할 때 SYN_RECV가 아주 많다면 TCP SYN 플러딩(Flooding) 공격일 가능성이 있다.

윈도우즈와 솔라리스에서는 SYN_RECEIVED으로, FreeBSD는 SYN_RCVD으로 표시.

ESTABLISHED : 서로 연결이 되어 있는 상태

위에서 192.168.123.10의 포트 32794과 218.xxx.xx.xx의 포트 22(ssh)이 서로 연결되어 있는 상태.

 

TCP 종료 단계

* 정상적인 연결 종료 과정

TCP A                                                                                     TCP B

  1. ESTABLISHED ESTABLISHED
  2. (Close)

FIN-WAIT-1       –> <SEQ=100><ACK=300><CTL=FIN,ACK>  –>  CLOSE-WAIT

  1. FIN-WAIT-2 <–  <SEQ=300><ACK=101><CTL=ACK>       <–   CLOSE-WAIT
  2. (Close)

TIME-WAIT      <–  <SEQ=300><ACK=101><CTL=FIN,ACK>  <–    LAST-ACK

  1. IME-WAIT –> <SEQ=101><ACK=301><CTL=ACK>         –>  CLOSED
  2. (2 MSL)

CLOSED

 

FIN_WAIT1     : 소켓이 닫히고 연결이 종료되고 있는 상태. 원격의 응답은 받을 수 있다.

솔라리스에서는 FIN_WAIT_1로 표시.

FIN_WAIT2     : 로컬이 원격으로 부터 연결 종료 요구를 기다리는 상태.

솔라리스에서는 FIN_WAIT_2로 표시.

CLOSE_WAIT : 원격의 연결 요청을 받고 연결이 종료되기를 기다리는 상태 .

원격으로 부터 FIN+ACK 신호를 받고 ACK 신호를 원격에 보냈다.

TIME_WAIT    : 연결은 종료되었으나 원격의 수신 보장을 위해 기다리고 있는 상태.

이 상태를 특히 자주 보게되는 경우 => Apache에서 KeepAlive를 OFF로 해둔 경우, Tomcat 서버를 쓰는 경우 등.

LAST_ACK    : 연결은 종료되었고 승인을 기다리는 상태.

CLOSED       : 완전히 연결이 종료된 상태.

 

※ 위의 FIN_WAIT1, FIN_WAIT2, CLOSE_WAIT 3개 상태는

연결 종료를 위해 서로간에 신호를 주고받는 과정에 나타나는 상태로 이해하면 된다.

종료 요청을 한 곳에서는 FIN_WAIT1, FIN_WAIT2, TIME_WAIT 상태가,

종료 요청을 받는 곳에서는 CLOSE_WAIT, LAST_ACK 상태가 표시된다.

 

TIME_WAIT 상태 없애기

이미 발생한 TIME_WAIT 상태는 일정시간이 지나면 없어지지만,

client가 server에 매우 빈번히 connect/disconnect를 반복한다면

많은 TCP port가 TIME_WAIT 상태가 되서 문제가 생길 수 있음.

 

client application에서 socket option 중 linger option을 off 시키면,

client에 의한 connection close시 TIME_WAIT 상태를 거치지 않고

ClOSED 상태로 바뀌게 되므로, TIME_WAIT 상태가 발생하지 않게 됨.

 

/* 중략 */

int sock

struct linger   ling;

 

ling.l_onoff = 1;

ling.l_linger = 0;      /* 0 for abortive disconnect */

 

setsockopt(sock, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling))

 

TCP 상태별 정의

ESTABLISHED

3단계 핸드쉐이킹 후 연결 성립

 

SYN_SENT

원격 호스트에 능동적인 개설 요청(능동적 열기)

 

SYN_RECV

네트워크 통한 연결요청 받음(수동적 열기)

 

FIN_WAIT1

능동적 닫기(active close) 요청을 한 상태

 

FIN_WAIT2

로컬에서 종결(FIN)세그먼트를 전송하였고 원격 시스템에서 이에 대한 확인메시지를 수신하였지만,

원격 애플리케이션이 작업을 종료하지 않아 원격 호스트의 종결 세그먼트를 기다리는 상태

 

TIME_WAIT

회선의 종결 절차가 완료되었지만 분실되었을지 모르는 느린 세그먼트를 위해

소켓을 열어 놓고 유지하고 있는 상태

 

CLOSED

회선이 종결되고 모든 자원을 해제한 상태

 

CLOSE_WAIT

수동적 닫기를 하고 있는 상태로 FIN 종결 세그먼트를 수신하고 이에 대한 확인 메시지를 전송한 상태

 

LAST_ACK

FIN 종결 요청을 받고 로컬에서도 회선 종결에 합의하여 종결을 요청(FIN)한 상태로

이에 대한 확인 메시지가 수신되면 회선이 종결됨

 

LISTEN

서버 애플리케이션에서 수동적 열기로 연결 요청을 기다리고 있는 상태

 

CLOSING

로컬 TCP는 FIN_WAIT_1에서 설명한대로 FIN 종결 세그먼트를 전송하였고,

LAST_ACK에서 설명한대로 원격 시스템의 종결 세그먼트도 수신하였지만,

FIN_WAIT_1 단계에서 전송한 세그먼트에 대한 확인 메시지(ACK)를 수신하지 못한 상태로

보통 확인 메시지가 전송 도중 분실되었다는 것을 나타냄

 

UNKOWN

소켓의 상태에 대해서 확인이 안되는 경우

[sqlite] 매우 가벼운 SQL ?? sqlite3 설치 및 이용하기

Sqlite3 설치는 yum install sqlite 으로 간단히 진행 할 수 있다.

모바일 등에서 최근 로컬 데이터베이스 저장용도 및 query용도로 매우 각광받고 있으므로, 필히 알아둘것, 참고로 이용법은 타 SQL 과 흡사하여 접근하기가 쉽습니당.

 

sqlite> create table members(id integer Primary key NOT NULL, name text NOT NULL, passwd text NOT NULL, msg text);

sqlite> .tables

members

sqlite> .schema members

CREATE TABLE members(id integer Primary key NOT NULL, name text NOT NULL, passwd text NOT NULL, msg text);

 

sqlite> insert into members(name,passwd,msg) values (‘username’,’PASSWORD’,’Administrator’);

sqlite> select * from members;

1|유저명|암호|태그명

sqlite> .mode header

Error: mode should be one of: column csv html insert line list tabs tcl

sqlite> .mode line

sqlite> select * from members;

id = 1

name = 유저

passwd = 암호

msg = 태그

sqlite> .mode list

sqlite> select * from members;

1|유저|암호|태그

sqlite> .mode column

sqlite> select * from members;

1           유저    암호   태그

sqlite> .headers on

sqlite> select * from members;

id          name        passwd      msg

———-  ———-  ———-  ————-

1           유저    암호   태그

sqlite>

 

 

.sqliterc 파일을 만들어서 환경을 읽어갈 수 있음.

sqlite> .mode list

sqlite> select * from members limit 10;

id|name|passwd|msg

1|유저|암호|태그

sqlite> .quit

 

[root@jinstalk ~]# sqlite3 /root/DB/member.db

— Loading resources from /root/.sqliterc

 

SQLite Version 3.7.17 2013-05-20 00:56:22

Enter “.help” for instructions

Enter SQL statements terminated with a “;”

sqlite> select * from members limit 10;

id          name        passwd      msg

———-  ———-  ———-  ————-

1           유저    암호   태그

sqlite> .exit

[root@jinstalk ~]# cat .sqliterc

.header on

.mode column

 

 

문법 :

sqlite> .help

.backup ?DB? FILE      Backup DB (default “main”) to FILE

.bail ON|OFF           Stop after hitting an error.  Default OFF

.databases             List names and files of attached databases

.dump ?TABLE? …      Dump the database in an SQL text format

If TABLE specified, only dump tables matching

LIKE pattern TABLE.

.echo ON|OFF           Turn command echo on or off

.exit                  Exit this program

.explain ON|OFF        Turn output mode suitable for EXPLAIN on or off.

.genfkey ?OPTIONS?     Options are:

–no-drop: Do not drop old fkey triggers.

–ignore-errors: Ignore tables with fkey errors

–exec: Execute generated SQL immediately

See file tool/genfkey.README in the source

distribution for further information.

.header(s) ON|OFF      Turn display of headers on or off

.help                  Show this message

.import FILE TABLE     Import data from FILE into TABLE

.indices ?TABLE?       Show names of all indices

If TABLE specified, only show indices for tables

matching LIKE pattern TABLE.

.load FILE ?ENTRY?     Load an extension library

.mode MODE ?TABLE?     Set output mode where MODE is one of:

csv      Comma-separated values

column   Left-aligned columns.  (See .width)

html     HTML <table> code

insert   SQL insert statements for TABLE

line     One value per line

list     Values delimited by .separator string

tabs     Tab-separated values

tcl      TCL list elements

.nullvalue STRING      Print STRING in place of NULL values

.output FILENAME       Send output to FILENAME

.output stdout         Send output to the screen

.prompt MAIN CONTINUE  Replace the standard prompts

.quit                  Exit this program

.read FILENAME         Execute SQL in FILENAME

.restore ?DB? FILE     Restore content of DB (default “main”) from FILE

.schema ?TABLE?        Show the CREATE statements

If TABLE specified, only show tables matching

LIKE pattern TABLE.

.separator STRING      Change separator used by output mode and .import

.show                  Show the current values for various settings

.tables ?TABLE?        List names of tables

If TABLE specified, only list tables matching

LIKE pattern TABLE.

.timeout MS            Try opening locked tables for MS milliseconds

.width NUM NUM …     Set column widths for “column” mode

.timer ON|OFF          Turn the CPU timer measurement on or off

 

 

외부 스키마 임포트

.import /paththosql/scheme.sql

 

 

 

 

들어가며

SQLite 데이터베이스를 짧은 시간안에 사용할 수 있도록 돕는게 이 문서의 목표입니다.

특징

여기서는 딱 3개만 짚어 보겠습니다. SQLite 홈페이지의 문서를 보면 다른 특징들도 나와 있습니다. 좀 더 관심있는 분들은 그곳을 함 들러보세요~

  1. Serverless

대부분의 데이터베이스 서버는 클라이언트/서버 구조를 취하고 있습니다. 허나 SQLite는 그렇지 않습니다.

  1. Single Database File

하나의 데이터베이스가 물리적으로 여러 디렉토리와 파일로 구성되는게 일반적입니다. SQLite는 하나의 데이터베이스마다 오직 하나의 물리적 파일만을 사용합니다.

  1. Manifest Typing

대부분의 데이터베이스는 컬럼에 자료형을 지정하고, 값을 저장할 때는 그 형(type)의 값들만이 들어갈 수 있습니다. 즉, 컬럼에 형이 있고 값 그 자체에는 형이 없는 격이죠. SQLite는 그 반대입니다. 컬럼에는 형이 없고 값 자체에 형이 있습니다.

설치하기

다운로드를 위해서 먼저 SQLite 홈페이지로 이동합니다. 그 다음, 다운로드 페이지로 가면 운영 체제별로 분류가 되어 있습니다.

여기서는 크게 두 가지로 살펴 보도록 하겠습니다: 이진 라이브러리 설치(윈도우즈)와 소스 설치. 많은 유닉스 계열의 운영 체제와는 다르게, 마이크로소프트의 윈도우즈 운영 체제는 C 컴파일러를 갖춘 경우가 매우 드뭅니다. 대부분의 윈도우즈 사용자들은 C 컴파일러가 없기 때문에, 미리 컴파일을 한 후에 바로 실행 가능한 형태로 배포하는게 일반적인 설치 형태입니다. 반면, 유닉스 계열의 운영 체제들은 대부분 C 컴파일러를 장착하고 있으며, 사용자들도 사용할 수 있기 때문에 소스 코드 형태로 다운로드받아 이를 컴파일하는 형태로 설치하는게 일반적인 설치 과정입니다.

그럼, 윈도우용부터 설치해 보도록 하겠습니다.

이진 라이브러리 설치

다운로드 페이지에서 윈도우즈 쪽으로 갑니다. 윈도우즈에도 여러 가지 라이브러리가 있습니다만, 특별한 이유가 없다면, 가장 첫 번째 것을 다운로드 합니다(현재 sqlite-3_3_17.zip). 그 다음 압축을 풀면, 설렁하니 단 한 개의 파일(sqlite3.exe)만이 나올겁니다. 음… 놀라지 마세요. 그게 다에요! 다시 말해, 이제 당장 실행할 수 있다는 뜻입니다.

DLL 형태를 원한다면 sqlitedll-3_3_17.zip를 다운로드 하면 됩니다.

마지막으로 한 마디: 윈도우즈 사용자라 해서 “꼭” 이진 라이브러리를 사용해야 한다는 법은 없습니다. 컴파일러가 있다면 소스 코드로 설치할 수 있습니다.

소스 설치

리눅스에서 함 해 보겠습니다. 소스는 SQLite 홈페이지의 다운로드 페이지에 얻을 수 있습니다; 저는 sqlite-3.3.17.tar.gz를 다운로드했습니다.

압축을 풀고 그 디렉토리로 갑니다. 그 다음, 빌드 디렉토리를 만든 후에 그곳으로 이동합니다. 설치 위치를 정한후에 컴파일/설치를 합니다. 다음은 설치 과정을 보여줍니다.

$ tar xvfz ./sqlite-3.3.17.tar.gz

$ cd sqlite-3.3.17

$ mkdir ./build

$ cd ./build

$ ../configure –prefix=/home/user1/sqlite3

$ make

$ make install

위에서 우리는 설치를 /home/user1/sqlite3에 했습니다. 만약 설치 위치를 정해주지 않으면 기본적으로 /usr/local/에 설치됩니다. 루트 권한이 없으면 그 곳에는 설치할 수 없죠~ 그럼, 이제 설치한 곳으로 이동한 다음, 뭐가 있는지 봅시다.

$ cd

$ cd ./sqlite3

$ ls

bin  include  lib

세 개의 디렉토리가 있습니다. bin 디렉토리에는 명령행 클라이언트가 있습니다. 그리고 include와 lib 디렉토리에는 각각 헤더 파일과 라이브러리가 있습니다. 그럼 제대로 설치되었는지 확인해 보죠; 데이터베이스를 만들고 그 안에 테이블도 하나 만들 겁니다.

$ ./bin/sqlite3 db_test

sqlite> CREATE TABLE tbl_test (One INTEGER, Two INTEGER);

sqlite> .tables

tbl_test

sqlite> .exit

자 위에서 db_test란 데이터베이스를 만들고 그 안에 tbl_test 테이블을 하나 만들었습니다. 데이터베이스 파일이 생겼는지 확인해 보세요. 여기까지 왔다면 설치가 제대로 된 거구요… 만약 아니라면, 불행히도 설치가 안 된 겁니다.

리눅스에는 autoconf와 libtool란 빌드 툴이 있기 때문에, 위에서 configure를 사용할 수 있었습니다. 만약 이 툴이 없다면 Makefile을 직접 작성해야 합니다. 그러나 친절하게도 Makefile.linux-gcc란 샘플이 있습니다. 이를 참고로 수정한 후에 make와 make install 명령을 주면 됩니다.

시스템 설치

각 운영 체제마다 시스템에 프로그램이나 라이브러리를 손쉽게 추가/설치/관리하는 메커니즘이 있습니다. 이렇게 시스템에 설치하는 것의 이점은, 한 번 설치로 모든 사용자들이 곧바로 사용할 수 있다는 거죠.

이 문서에서는 각 시스템의 구체적인 설명은 생략하겠습니다.

한 가지 주의할 점은 시스템에 따라 SQLite의 라이브러리만 설치되는 경우가 있습니다. 그러면 헤더 파일이 없기 때문에, 사용할 때는 문제가 없으나 개발시에 문제가 됩니다. 개발을 원하다면, 당근, 헤더 파일까지 시스템에 설치해 줘야 합니다.

저장형과 컬럼 친화성

SQLite에는 저장형(Storage Class)와 컬럼 친화성(Column Affinity)이 있습니다.

저장형은 각 값에 붙여지는 태그이며, 정렬이나 비교와 같은 연산을 실행할 때 사용됩니다. 컬럼 친화성은 다른 데이터베이스와 호환을 위해 제공됩니다. 이미 오라클이나 MySQL과 같은 데이터베이스에 경험이 있는 분들에게는 이 부분이 많이 헷갈릴 수 있습니다. 그럴 경우, 이 저장형과 컬럼 친화성을 받아 들이기가 힘들 수 있는데, 한 가지 요령은 기존에 알고 있던 데이터베이스에 대한 지식이나 경험의 일부를 잠시 잊어버리면 수월합니다(실은 제가 그랬습니다~ 🙂

저장형

저장형(Storage Class)은 각 값에 붙는 타입입니다. 다시 한 번 강조하자면, 각 값에 붙는 타입입니다. 오라클이나 MySQL 같은 경우에는 타입이 각 컬럼에 부여됩니다. 예를 들어, MySQL에서 테이블을 만들 때, 어떤 컬럼의 타입을 정수로 결정하면, 이후로 그 테이블의 그 컬럼에는 정수만이 들어갈 수 있습니다. 다시 말해, 정수가 아니면 안 되는 거죠. SQLite는 이와 같지 않습니다.

다음은 SQLite의 다섯 저장형입니다:

NULL:    값이 NULL인 경우.

 

INTEGER: 부호 있는 정수. 상황에 따라 1, 2, 3, 4, 6, 8 바이트가 됨.

 

REAL:    부동소수점. IEEE 부동소수 규격에 따른 8바이트.

 

TEXT:    문자(열). 기본적으로 UTF-8으로 저장되며 UTF-16 BE나 UTF-16 LE를 사용할 수 있음.

 

BLOB:    이진 데이터. 외부에서 전달된 데이터를 그대로 저장됨.

위 저장형은 다음 절에서 설명하는 컬럼 친화성과 함께 봐야 이해가 되므로, 저장형은 SQLite에서 타입을 의미한다는 정도만 알고 일단 패스!

컬럼 친화성

먼저, 우리에게 익숙한 다음 쿼리로 시작해 보겠습니다.

sqlite> CREATE TABLE tbl_test (One INTEGER, Two INTEGER);

위 쿼리로 두 개의 컬럼(One, Two)이 있는 테이블(tbl_test)을 하나 만들었습니다. 두 컬럼 모두 정수형이기 때문에, 위 테이블에는 정수만이 들어갈 수 있습니다. 그렇죠? 그러나 SQLite는 다릅니다! 다음으로 직접 확인해 보죠.

sqlite> INSERT INTO tbl_test VALUES (123, 456);

sqlite> INSERT INTO tbl_test VALUES (123, 456.7);

sqlite> INSERT INTO tbl_test VALUES (123, 456.0);

sqlite> INSERT INTO tbl_test VALUES (123, ‘456’);

sqlite> INSERT INTO tbl_test VALUES (123, ‘456two’);

sqlite> INSERT INTO tbl_test VALUES (123, ‘ant’);

sqlite> INSERT INTO tbl_test VALUES (123, ant);

위 실행중에서 가장 마지막 것만 오류가 발생하고 나머지는 실행됩니다. 즉 값이 테이블에 저장됩니다. 다음처럼 직접 확인해 보세요.

sqlite> SELECT * FROM tbl_test;

위에서 테이블을 만들 때, INTEGER란 키워드를 사용했는데 이는 컬럼 친화성을 지정하는 키워드 중에 하나였습니다. SQLite에는 모두 다섯 개의 컬럼 친화성이 있습니다: TEXT, NUMERIC, INTEGER, REAL, NONE.

자~ 여기서 맥(?)을 함 짚고 넘어 가겠습니다: 테이블을 생성하는 쿼리문이 동일하기 때문에, 여러분은 위의 INTEGER가 컬럼 타입이라고 생각하게 된 겁니다. SQLite에 서는 컬럼 타입(Column Type)이 아니라 컬럼 친화성(Column Affinity)으로 사용되고 있습니다. 컬럼 타입은 딱 하나를 결정하는 것이고, 컬럼 친화성은 어떤 우선 순위를 취할지 결정하는 겁니다. 어떤 우선 순위라?

우리는 테이블을 만들고 거기에 데이터를 저장합니다; 레코드를 기본 단위로 저장합니다. 위 테이블예에서, 오라클이나 MySQL은 레코드를 저장할 때마다 컬럼의 값들이 항상 정수입니다. 레코드가 추가되더라도 이건 변하지 않고 고정된 거죠. SQLite에서는 동일한 컬럼일지라도 각 레코드마다 다른 타입을 가질 수 있습니다.

아래 쿼리는 위에서 사용했던 것과 동일한데, 각 쿼리의 끝에 저장형을 보여주고 있습니다.(컬럼 친화성이랑 헷갈리지 마세요)

sqlite> INSERT INTO tbl_test VALUES (123, 456);       –(INTEGER, INTEGER)

sqlite> INSERT INTO tbl_test VALUES (123, 456.7);     –(INTEGER, REAL)

sqlite> INSERT INTO tbl_test VALUES (123, 456.0);     –(INTEGER, INTEGER)

sqlite> INSERT INTO tbl_test VALUES (123, ‘456’);     –(INTEGER, INTEGER)

sqlite> INSERT INTO tbl_test VALUES (123, ‘456two’);  –(INTEGER, TEXT)

sqlite> INSERT INTO tbl_test VALUES (123, ‘ant’);     –(INTEGER, TEXT)

sqlite> INSERT INTO tbl_test VALUES (123, ant);       –ERROR

위 쿼리에서 눈여겨 볼 부분은 두 번째 컬럼(컬럼 Two, 컬럼 친화성 INTEGER)입니다. 먼저 첫 번째 쿼리에서, 정수 값(456)이 입력되었으므로 저장형은 INTEGER가 됩니다.(INTEGER란 키워드는 컬럼 친화성과 저장형에 모두 있으므로 헷갈리지 마세요) 두 번째 쿼리에서는 정수가 아닙니다(456.7). SQLite는, 컬럼 친화성이 INTEGER이므로, 먼저 이 값이 정수가 될 수 있는지 확인합니다. 그런데 정수가 될 수가 없기 때문에 차선으로 REAL 저장형을 선택한 것입니다. 세 번째 쿼리에서도 정수로 변환 가능한지 확인하는데, 이번에는 가능합니다. 때문에 INTEGER 저장형을 부여합니다. 네 번째도 세번째에서와 마찬가지로 정수로 변환 가능하므로 INTEGER 저장형을 부여했습니다. 그 다음 값(‘456two’)은 어떻습니까? 이 값은 정수가 될 수도 없고 부동 소수가 될 수도 없습니다. 그 다음으로 TEXT로 변환 가능하기 때문에 TEXT 저장형을 부여했습니다. 그 다음 여섯 번째도 마찬가지입니다. 마지막 쿼리에서의 값(ant)은 정수도 부동 소수도 될 수가 없기 때문에 텍스트가 되야 하는데, 작은 따옴표가 없기 때문에 에러를 발생합니다. 컬럼 친화성에 상관없이 작은 따옴표를 사용하지 않는 값의 경우에는 숫자만이 가능합니다.

음, 여기서 말한 컬럼 친화성이란 입력되는 값에 따라 어떤 타입을 우선해서 선택할까를 의미합니다. 그럼 다음 번에는 다섯 개 컬럼 친화성의 우선 순위에 대해서 알아 보도록 하겠습니다.

자동 증가 Autoincrement

자동 증가는 보통 테이블의 키로 사용됩니다. 그래서 유일한 값을 갖는게 중요하지요. 다른 테이블에서 외래키(foreign key)로 사용될 때도 필요하구요. 다음 처럼 간단합니다.

CREATE TABLE tbl_test (

RowID INTEGER PRIMARY KEY AUTOINCREMENT,

Name  TEXT,

Age   INTEGER

);

위 테이블에서 RowID 열이 자동 증가 합니다. 열 이름이 반드시 ‘RowID’일 필요는 없구요~

명령행 클라이언트

자 이제 설치했으니까 SQLite를 실행해 봅시다. 실행 경로에 SQLite가 잡혀 있는지 다시 한 번 점검해 주시구요.

$ sqlite3 db_test

간단합니다. 명령어를 치고 원하는 데이터베이스를 입력합니다. 만약 그 데이터베이스가 없으면 새로 생기고, 이미 존재하면 그걸 열고 들어가게 됩니다. 아무런 설정이 필요 없어요;SQLite 문서에는 이를 Zero Configuration이라 했습니다. 그 다음, 어떤 테이블이 있는지 살펴 볼까요.

sqlite> .tables

앞에 점(dot)을 주의하시구요. SQLite에 기본적으로 딸려 오는 명령행 클라이언트는 닷 명령으로 SQL 쿼리와 기타 명령을 구분합니다. 자 그럼 나가기 전에 테이블을 하나 만들어 봅시다.

sqlite> CREATE TABLE tbl_person (Name TEXT, Age INTEGER);

이제 프로그램을 종료하기 전에, 도움말을 다음처럼 보구여~

sqlite> .help

sqlite> .exit

자 이제 데이터베이스를 새로 만들고 간단한 테이블을 만든 후에 점잖게(?) 일을 마무리 했습니다. 함 디렉토리를 확인해 보세요. 데이터베이스 파일이 생겼을 거에요: db_testSQLite의 데이터베이스는 한 개의 파일에 모든게 들어있기 때문에, 데이터베이스를 다른 곳으로 옮기고자 할 때 작업이 아주 간단해요. 음악이나 이미지 파일 복사해 옮기듯이 하면, 그게 다에요.

그리고 중간에 도움말을 잠깐 보았습니다. 아주 썰렁합니다. 그래서 별 도움이 안 될 것 같지요? 그럴수도 있구요 🙂 여기서는 그냥 직접 해 보구 ‘아 이런게 있구나’ 정도면 충.분.합니다.

그럼 이번에는 .schema 명령에 대해 알아 보죠. 이 명령은 테이블 스키마, 즉 구조를 살펴 볼 때 사용합니다. 일단 보죠.

sqlite> .schema

sqlite> .schema tbl_test

위의 첫 번째 예처럼 그냥 .schema 명령만 주면 데이터베이스에 있는 모든 테이블의 스키마를 볼 수 있습니다. 특정 테이블의 스키마만 보고자 할 때는 두 번째 예처럼 뒤에 테이블 이름을 적어주면 그만 입니다.

이제 출력 포맷을 바꿔주는 명령을 몇 개 알아 보겠습니다. 테이블에 SELECT 쿼리를 주면, 결과가 한 줄당 한 개의 열이 화면에 출력됩니다. 그리고 각 컬럼은 수평바 |로 구분되지요. 다음 예를 보면 쉽게 이해될 겁니다.

sqlite> select * from tbl_test;

123|456

789|ant

sqlite> .separator “!”

sqlite> select * from tbl_test;

123!456

789!ant

sqlite> .separator “\t”

sqlite> select * from tbl_test;

123     456

789     ant

sqlite>

위 예에서 마지막 “\t”은 탭을 의미하고, 텍스트 편집기에서 탭 키를 누른 것과 똑같이 보입니다.

자 이번에는 .mode 명령을 사용해 보죠. 이 명령은 뒤에 원하는 모드를 적어주어야 합니다. 모두 5개가 있으면 기본값은 “list”입니다: list, line, column, insert, html. 여기서는 두 개의 예만 보도록 하겠습니다. 나머지는 여러분들이 직접 바꿔가면서 확인해 주세요.

sqlite> .mode line

sqlite> select * from tbl_test;

One = 123

Two = 456

 

One = 789

Two = ant

sqlite> .mode insert tbl_test

sqlite> select * from tbl_test;

INSERT INTO ‘tbl_test’ VALUES (123, 456);

INSERT INTO ‘tbl_test’ VALUES (789, ‘ant’);

sqlite> .mode list

sqlite> .mode column

sqlite> .mode html

두 번째 insert 모드는 출력 결과를 삽입용 SQL 쿼리문으로 보여줍니다. 이 명령은 다른 것들과 달리, 뒤에 원하는 테이블 이름을 추가 해야 합니다.

음… 지금까지의 출력에는 컬럼 이름이 나오질 않았습니다(line 모드 제외). 컬럼 이름을 출력에 추가하려면 .headers 명령을 이용합니다. 기본값으로는 “off” 이니까 이를 “on”으로 다음처럼 설정해 줍니다.

sqlite> .headers on

간단하니까 실행 결과를 꼭! 확인해 보세요.

이번에는 .output 명령을 알아 봅시다. 지금까지 명령이나 쿼리의 결과는 화면에 뿌려졌습니다. 이를 파일로 보내는 방법이 있습니다.

sqlite> .output outfile.txt

위 명령 이후에는 화면에 나오던 것들이 모두 outfile.txt로 보내져 저장됩니다. 이를 원상태로 복원하려면 다음처럼 합니다.

sqlite> .output stdout

자 이제 .dump 명령을 알아 봅시다. 이는 우리가 소위 “덤프 뜬다”라고 하는 겁니다. 이는 한 개의 테이블 또는 데이터베이스에 있는 모든 테이블을 현재 상태로 만들어 주는 SQL 명령입니다. 그러니까 덤프를 뜨면, 현 데이터베이스를 다른 데이터베이스로 옮기는 작업이 수얼해 질 수 있고, 백업으로도 사용할 수 있습니다.

sqlite> .dump

sqlite> .dump tbl_test

첫 번째 덤프 명령은 데이터베이스 내에 있는 모든 테이블에 적용되고, 후자는 특정 테이블에만 적용됩니다. 자 그럼 이제, 예를 들어, 전체 데이터베이스를 파일로 덤프 뜰 수 있겠어요? 음… 제가 함 해 볼께요.

sqlite> .output db_test.dump

sqlite> .dump

위에서는 우선 출력을 덤프 파일(db_test.dump)로 설정하고 그곳으로 덤프 결과를 보냈습니다. 이번에는 좀 더 간단하게 셸 명령행에서 해 보도록 하겠습니다.

$ sqlite3 db_test .dump > db_test.dump

위 명령은 우선, 데이터베이스(db_test)를 열고 덤프 명령(.dump)를 실행합니다. 그러면 결과가 화면에 출력되야 하는데, 여기서는 덤프 파일(db_test.dump)로 방향을 바꿨습니다. 함 덤프 파일이 생겼는지, 그리고 그 안에 어떤 내용이 있는지 확인해 보세요.

그럼 이번에는 반대로, 이렇게 만든 덤프 파일을 데이터베이스로 넣어 보겠습니다; 먼저 새로운 데이터베이스를 하나 만든 다음에 그곳에 복사합니다.

$ cat ./db_test.dump | sqlite3 db_test2

위 명령으로 db_test가 db_test2란 데이터베이스로 복사되었습니다. 이번에도 함 (직접:) 확인해 보세요.

기본값으로 설정되어 있는 게 맘에 들지 않으면, 시작할 때마다 본인이 원하는데로 설정을 해야 합니다. 매번 이렇게 한다는 건 정말 지루하기 짝이 없는 일이죠. 바로 이를 해결해 주는게 설정 파일입니다. 설정 파일은 기본적으로 ~/.sqliterc 파일이며, 이를 다음처럼 바꿔 줄 수도 있습니다.

$ sqlite3 -init ~/.another_sqliterc …

다음은 저의 설정 파일입니다.

.header on

.separator “\t”

많이 썰렁하죠. 저는 닷(.) 명령만 사용했는데 쿼리도 이 설정 파일에 넣어 줄 수 있습니다. 그렇지만 어떤 쿼리를 설정 파일에 넣은 것은 권장되지 않습니다. 암튼, 저는 SELECT 쿼리의 결과에서 컬럼 이름이 나오고 탭으로 간격을 맞춰 출력되는 걸 좋아합니다

[출처] sqlite 사용법|작성자 dw21008

 

 

$ sqlite test_db

SQLite version 2.8.6

Enter “.help” for instructions

sqlite>

쉘에서 이렇게만 하면 현재 디렉토리에 test_db 라는 파일이 하나 만들어집니다.

이 파일(DB)을 php에서 사용하려면 당연히 웹서버가 읽고 쓸수 있는 권한이 있어야

합니다.

 

sqlite> create table test_tb ( id int PRIMARY KEY, name varchar(30));

테이블 test_tb 를 만듭니다.

sqlite> .tables //테이블목록 보기

test_tb

sqlite> .schema test_tb // 테이블의 구조를 봅니다.

create table test_tb ( id int PRIMARY KEY, name varchar(30));

sqlite> insert into test_tb values ( 1,’권기성’);

// AUTO_INCREMENT 기능하는 INSERT

sqlite> insert into test_tb values((SELECT max(id) FROM test_tb)+1,’권기성2′);

sqlite> select * from test_tb;

1|권기성

2|권기성2

 

sqlite> create index name_idx on test_tb (name) ; //인덱스 만들기

 

sqlite> begin ; //트랜잭션도 가능

sqlite> insert into test_tb values ( 3,’김기성’);

sqlite> select * from test_tb;

1|권기성

2|권기성2

3|김기성

sqlite> rollback; //롤백

sqlite> select * from test_tb;

1|권기성

2|권기성2

 

sqlite> .output backup.txt //다음줄 select 의 결과가 backup.txt 파일로 저장됨

sqlite> select * from test_tb ;

sqlite> .exit //종료

 

// 쉘에서 test_db 를 dump 받아서 압축함 ( mysqldump 와 비슷 )

$ echo ‘.dump’ | sqlite test_db | gzip -c > test_db.dump.gz //백업하기

$ zcat test_db.dump.gz | sqlite test_db //복원하기

 

==PHP 소스

 

– 간단한 사용법은 아래와 같습니다. DB 연결부분은 쉽게 이해가 가실겁니다.

– 실패하기 제일 쉬운 이유는 DB 인 test_db 라는 파일의 경로가 제대로 설정되어야하고

웹서버가 읽고 쓸수 있는 권한이 주어져야합니다.

 

<?php

// PEAR DB 연결

require_once ‘DB.php’;

require_once ‘DB/sqlite.php’;

 

// DSN 정의 – DB 파일의 경로와 퍼미션 주의

$dsn = array (

‘phptype’ => “sqlite”, ‘database’ => “./test_db”,

‘mode’ => 0644

);

$db = &new DB_sqlite();

$db->connect($dsn, array(‘persistent’=> true) );

$table = ‘test_tb’; // 테이블명

 

//입력

$result = $db->query(“INSERT INTO $table VALUES (9,’아무개’);”);

 

printf(“affectedRows:\t\t%s\n<br>”, $db->affectedRows() );

printf(“getLastInsertId:\t%s\n<br>”, $db->getLastInsertId() );

$result = $db->query(“SELECT * FROM $table;” );

while($row = $db->fetchrow($result)){

print_r($row ); echo “<br>”;

}

$db->disconnect();

?>

 

 

 

[python] Game Dev framework (pygame install)

Pygame.org

 

 

For mac : homebrew

brew install homebrew/python/pygame

 

 

 

빌드 후,,,,(이거 겁나 오래걸리고, 씨퓨도 많이 먹는다)

 

mkdir -p /Users/hongsungho/Library/Python/2.7/lib/python/site-packages

echo ‘import site; site.addsitedir(“/usr/local/lib/python2.7/site-packages”)’ >> /Users/hongsungho/Library/Python/2.7/lib/python/site-packages/homebrew.pth

 

 

2.7 모듈 패스를 지정해주어야, 확인 가능염,

Pip list 로 확인하고, import pygame으로 가능.