Solaris에서 DHCP를 이용시 hostname 변경 방법

고정IP를 사용하지 않는 사람들의 경우 대부분 DHCP를 이용해야지만 Solaris에서 인터넷을 사용할 수 있는걸로 알고 있습니다.
하지만 DHCP를 이용하게 되면 hostname이 unknown 로 되어 있어 수정을 할려고 하니 잘 되지 않더군요
그래서 제가 자료를 찾아서 unknown 를 test 성공한 내용을 적도록 하겠습니다.

일단 vi를 이용하여 수정하는 파일들을 열거하도록 하겠습니다.

/etc/nodename  <- 파일이 없다면 생성해서 만들어주세요!
/etc/hostname.hme0   <- hme0은 네트워크식별자 입니다.
/etc/inet/hosts
/etc/inet/ipnodes
/etc/net/ticlts/hosts
/etc/net/ticots/hosts
/etc/net/ticotsord/hosts
/etc/init.d/network
/etc/init.d/inetsvc


수정 방법

# vi /etc/nodename
test

# vi /etc/hostname.hme0
test

# vi /etc/inet/hosts

127.0.0.1       localhost       loghost test
192.168.1.70    test    # Added by DHCP    <- unknown를 test로 수정 후 저장


# vi /etc/inet/ipnodes

::1             localhost
127.0.0.1       localhost
192.168.1.70    test    #Added by DHCP  <- unknown를 test로 수정 후 저장


# vi /etc/net/ticlts/hosts

# RPC hosts
test test    <- unknown unknown 되어 있는걸 test test 로 수정 후 저장

# vi /etc/ent/ticots/hosts

# RPC hosts
test test    <- unknown unknown 되어 있는걸 test test 로 수정 후 저장


# vi /etc/net/ticotsord/hosts

# RPC hosts
test test    <- unknown unknown 되어 있는걸 test test 로 수정 후 저장


# vi /etc/init.d/network

#
# If the netstrategy was unsuccessful or we haven't got a locally configured
# name, default to "unknown"
#
if [ -z "$hostname" ]; then
        hostname="test"
fi

/sbin/uname -S $hostname

위의 부분을 찾아 hostname="unknown" 되어 있는걸 hostname="test"로 수정 후 저장


# vi /etc/init.d/inetsvc

 #
        # if DHCP doesn't return a hostname, use "unknown" so
        # client can resolve IP address into a local hostname.
        #
        hostname=`/sbin/dhcpinfo Hostname`
        if [ -z "$hostname" ]; then
                hostname="test"
        fi

위의 부분을 찾아 hostname="unknown" 되어 있는걸 hostname="test"로 수정 후 저장

이제 reboot 한후 hostname이 test 로 올라오는걸 확인하시면 됩니다.

 



SPARC: 디스크 없는 클라이언트 설치 중 전원 관리가 활성화된 경우 Sun Blade 1000 및 Sun Blade 2000 시스템에서 커널 장애 발생(4985416)

Solaris 9 4/04 릴리스에서는 Sun BladeTM 1000 또는 Sun BladeTM 2000 시스템에서 디스크 없는 클라이언트 설치 중 전원 관리가 활성화되었다면 커널 장애가 발생합니다. 유휴 시간이 지난 후 시스템 장애가 발생합니다.

다음과 같은 오류 메시지가 나타납니다.


/usr/sbin/pmconfig: /etc/power.conf line (18) failed to convert mountpoint to prom name.

이 메시지는 /var/adm/messages 파일에도 기록됩니다.

해결 방법: 이 문제를 방지하려면 다음 단계를 수행합니다.

  1. /etc/power.conf 파일을 편집하여 전원 관리를 비활성화합니다. autopm 항목을 default 에서 disable로 변경합니다.

  2. /etc/power.conf 파일을 편집한 후 다음 옵션 중 하나를 선택합니다.

    • 변경 사항을 적용하려면 시스템을 재부트합니다.

    • 수퍼유저가 되도록 합니다. 그리고 다음 명령을 실행합니다.


      # /usr/sbin/pmconfig

SSH, FTP 접속 딜레이가 생길때...

Posted 2009. 5. 22. 16:36

처음 설치후 한동안 SSH, FTP 등 접속을 할때 빠르게 로그인창이 떳었는데 요즘은 계속 딜레이가 5초 이상이 발생하여
이에 대한 대처 방법을 적도록 하겠습니다.


1. SSH

SSH의 경우 대개 config 를 수정하면 해결이 되더군요
일단 sshd_config 를 수정해야하니 find 명령어로 찾도록 하겠습니다.

# find / -name sshd_config
/usr/local/etc/sshd_config

위의 디렉토리에 있네요.
그럼 수정을..
# vi /usr/local/etc/sshd_config

--------------------
#UseLogin no
#UsePrivilegeSeparation yes
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS yes
#PidFile /var/run/sshd.pid
#MaxStartups 10
#PermitTunnel no
-----------------------------

맨밑으로 가시고 #UseDNS yes 부분이 있습니다.  이부분을 주석 제거하고 yes를 no로(DNS Server 일 경우 yes 그대로) 하시면 됩니다.

UseDNS no

이렇게 수정하고 저장한다음 SSHD를 재시작 해주시면 됩니다.


2. FTP

FTP의 경우는 대부분(?) resolv.conf 부분에서 딜레이가 발생합니다.

# vi /etc/resolv.conf

제일 첫번째줄에 nameserver 168.126.63.1 (KT DNS) 로 해 보세요.
순서를 바꾸는거죠. ^^;
그리고 /etc/hosts 여기에 접속할 ip 를 추가하면 딜레이 되는 부분이 어느정도 해결이 될겁니다.

MySQL 메뉴얼

Posted 2009. 3. 26. 11:43


MySQL 튜토리얼

번역: 이상용(sangyong@nownuri.net)
번역일자: 1999년 9월 9일
오타수정: 1999년 10월 13일(capricon@g2j.co.kr님의 지적)

------------------------------------------------------------------------------
다음 문서는 MySQL 3.22.25 버전 매뉴얼의 8장 부분을 번역한 것입니다. 보고
오역이나 내용이 이상하다면 위의 전자우편 주소로 연락해 주면 고맙겠습니다.
직역한 것도 있고 의역한 것도 있고 내용 순서가 바뀐 것도 있고, 제가
추가한 것도 있습니다. 원문과는 내용이 다른 부분도 많을 것입니다.
이점 참고하기 바랍니다.
------------------------------------------------------------------------------

mysql이라는 클라이언트 프로그램을 이용하여 MySQL을 익혀 보도록 하자. mysql은
간단히 데이터베이스를 만들고 사용할 수 있게 해주는 프로그램으로 '터미널 모니터'
혹은 간단히 '모니터'라고도 한다.

mysql은 대화식 프로그램으로서 서버에 연결하고, 질문을 수행하고, 결과를 화면에
보여주는 일을 한다. mysql은 배치 모드(batch mode)에서도 사용할 수 있다.

미리 파일에 sql 명령문을 넣어두고 mysql에게 파일의 명령을 수행하라고 하면
된다(뒤에서 알아 보겠지만 'mysql -vvv < batch_test.txt' 식으로 사용하면 된다).

mysql의 옵션들을 보려면 --help 옵션을 붙여서 실행하면 된다:

shell> mysql --help

이 튜토리얼에서는 mysql이 설치되어 있으며 접근할 수 있는 MySQL 서버가 있다는
것을 가정한다. 그렇지 않으면 MySQL 관리자에게 문의하라(여러분이 관리자라면
MySQL 문서의 다른 부분을 살펴볼 필요가 있을 것이다).

본 튜토리얼에서는 데이터베이스를 설계하고 사용하는 모든 과정을 다룬다. 이미
존재하는 데이터베이스를 사용하는 것에만 관심이 있다면 데이터베이스와 그 안에
있을 테이블을 만드는 방법을 설명한 절은 건너뛰어도 좋다.

튜토리얼 성격의 글이라 자세한 것은 설명되지 않는다. 여기에 언급된 것에 대해
더 자세히 알고 싶거든 MySQL의 관련 매뉴얼을 보면 된다.

shell>은 쉘 프롬프트를, mysql>은 MySQL 프롬프트를 나타낸다.


1. 서버에 연결하기/연결끊기

서버에 접속하려면 mysql 명령을 내릴 때 MySQL 사용자 이름과 대개의 경우
패스워드를 써 주어야 할 것이다. 서버가 여러분이 로긴한 컴퓨터가 아닌 것에서
운영된다면 호스트 이름도 써줄 필요가 있을 것이다(호스트 이름, 사용자 이름,
패스워드). 모든 것을 알았다면 다음처럼 연결할 수 있다:

shell> mysql -h host -u user -p
Enter password: ********

******* 부분은 패스워드다. 'Enter password' 프롬프트가 보이면 패스워드를
쳐주면 된다. 성공하면 간단한 소개 메시지들과 'mysql>' 프롬프트를 볼 수
있을 것이다.

shell> mysql -h host -u user -p
Enter password: ********
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 459 to server version: 3.22.20a-log

Type 'help' for help.

mysql>


'mysql>' 프롬프트가 의미하는 바는 준비되었으니 명령어를 입력하라는 말이다.

어떻게 설치하는 가에 따라 MySQL은 로컬 호스트(local host)에서 운영되는
서버에 "무명의 사용자(anonymous user)"로 접속할 수 있게 한다. 이럴 경우에는
단순히

shell> mysql

처럼 해서 연결할 수 있다.

성공적으로 접속하였다면 'mysql>' 프롬프트에서 언제든지 'QUIT'이라고 쳐서
서버에서 나올 수 있다:

mysql> QUIT
Bye

Ctrl키와 D 키를 동시에 눌러 빠져 나올 수도 있다.

이어지는 절에서 나오는 대부분의 예는 서버에 연결한 상태라는 것을 가정한다.
'mysql>' 프롬프트는 서버에 연결된 상태라는 것을 나타낸다.


2. 질문 하기(Entering Queries)

이전 절에서 언급하였듯이 서버에 접속된 것을 확인하자. 이렇게 한다고 작업할
어떤 데이터베이스도 선택하는(역자주: USE 명령어를 이용하여 데이타 베이스를
쓰겠다고 해야지만 사용할 수 있습니다) 것은 아니지만 어쨋든 접속은 해야 한다.
지금 상황에서는 데이터베이스안에 테이블을 만들고, 테이블에 자료를 올리고,
테이블에서 자료를 빼내는 것보다는 질문하는 법을 약간이라도 배우는 게 더
중요하다. 이번 절에서는 명령어 입력의 기본 원칙을 몇가지 질문 예를 통해 알아
본다. 예를 통해 어떻게 mysql이 동작하는지 익숙해질 것이다.

아래에 MySQL의 버전과 오늘 날짜를 출력하는 명령어를 보인다. 'mysql>'
프롬프트다음에 나오는 대로 쳐 넣자. 그리고 엔터키를 친다.

mysql> SELECT VERSION(), CURRENT_DATE;
+-------------+-----------------+
| VERSION() | CURRENT_DATE |
+-------------+-----------------+
| 3.22.20a-log| 1999-03-19 |
+-------------+-----------------+
1 row in set (0.01 sec)
mysql>

이 예로부터 mysql에 대한 몇가지 것들을 알 수 있다:

● 명령은 SQL 문과 그 뒤에오는 세미콜론(;)으로 이루어진다(세미콜론이 필요없는
예외가 있긴하다. QUIT이 그 중 하나다. 나중에 이것에 대해 다시 언급하겠다).

● 여러분이 명령을 내리면, mysql은 서버로 그 명령을 보내어 실행되게 하고, 그
결과를 보여주고 다시 명령 대기 상태 프롬프트('mysqld>')를 낸다.

● mysql은 테이블 형식(행과 열로 이루어진)으로 결과를 보여준다. 첫 행은 각
열에 대한 라벨을 갖고 있다. 두번째 행 부터는 질문의 답이 놓인다. 보통, 열의
라벨은 데이터베이스 테이블에서 가져오는 열의 이름이다. 방금 보인 것처럼
테이블의 열 이름이 아닌 표현식(expression)을 사용할 때는 라벨명은 그 표현식이
된다.

● mysql은 행의 수와 명령 실행 시간(대략적인 서버 성능 측정 도구다)을 보여
준다. 명령 실행 시간은 정확한 값은 아니다. 왜냐하면 이 시간은 wall clock
time(CPU 시간이 아니다)이라는 것과 서버 부하 및 네트워크 부하에 의한
지연시간에 영향을 받기 때문이다(앞으로 나올 예에서는 지금 설명한 부분은
나타내지 않겠다).

키워드(역자 주:'예약어'라고 합니다. 미리 예약된 것이라 마음대로 사용할 수
없는 이름입니다)는 대문자로 하든, 소문자로 하든 상관없다. 아래 세개의 명령은
다 동일하다:

mysql> SELECT VERSION(), CURRENT_DATE;
mysql> SELECT version(), current_date;
mysql> seLect vErSiOn(), current_DATE;

다른 예를 하나 더 살펴보자. mysql을 간단한 계산기로 사용한 예이다:

mysql> SELECT SIN(PI()/4), (4+1)*5;
+-------------------------+
| SIN(PI()/4) | (4+1)*5) |
+-------------+----------+
| 0.707107 | 25 |
+-------------+----------+

지금까지의 예에서 명령어는 비교적 짧았고, 한 줄 짜리였다. 한줄에 여러 명령을
기술할 수 있다. 각 명령을 세미콜론으로 끝내기만 하면 된다:

mysql> SELECT VERSION(); SELECT NOW();
+------------+
| VERSION() |
+------------+
|3.22.20a-log|
+------------+

+-----------------------+
| NOW() |
+-----------------------+
| 1999-03-19 00:15:33 |
+-----------------------+

명령어는 한줄에 모두 다 기술해야만 하는 건 아니다. 긴 명령인 경우 몇 줄에
걸쳐 기술할 수 있다. mysql은 세미콜론을 보고 어디서 명령이 끝나는지를
분간한다(mysql은 임의의 포맷을 갖는 입력을 받아 들인다. 입력 줄을 모아
세미콜론을 볼 때까지 실행한다).

여러 줄에 걸쳐 명령을 준 예를 보자:

mysql> SELECT
-> USER()
-> ,
-> CURRENT_DATE;
+-------------------+-------------+
| USER() | CURRENT_DATE|
+-------------------+-------------+
| joesmith@localhost| 1999-03-18 |
+-------------------+-------------+

여러줄을 입력할 때 첫줄을 입력하고 엔터키를 쳤을때 프롬프트가 'mysql>'에서
'->'로 바뀐 것을 주목하라. 이것은 아직 명령이 다 완성되지는 않았으며, 따라서
더 입력을 기다린다라고 mysql이 여러분에게 알리는 것이다. 프롬프트는 여러분의
친절한 안내자다. 귀한 정보를 여러분에게 알려 준다. 프롬프트가 알려주는
것들을 통해 mysql이 무엇을 기다리고 있는지 항상 알 수 있을 것이다.

명령어 입력 도중 취소하려면 \c를 쳐주면 된다:

mysql> SELECT
-> USER()
-> \c
mysql>

프롬프트 변화를 잘 보라. \c를 친후 'mysql>'로 바뀌었다. 새 명령어를 받아들일
준비가 되었다는 것을 알리는 것이다.

다음 표는 마주치게 될 프롬프트들과 그 의미를 설명한 것이다.


프롬프트 의미
-----------------------------------------------
mysql> 새 명령을 받아 들일 준비가 되었음
-----------------------------------------------
-> 명령어를 여러 줄에 기술할 때 다음 줄을
기다리고 있음을 의미
-----------------------------------------------
'> 다음줄 입력을 나타낸다. 현재 '로 시작하는
문자열을 수집하는 중이라는 것을 나타냄
(문자열 입력을 끝내려면 문자열을 다 입력
한 후 '를 붙여 줄것)
-----------------------------------------------
"> '>와 같다. 단지 차이는 문자열을 '가 아니
라 " 로 두른다는 점이다.
-----------------------------------------------


세미콜론을 붙이는 것을 잊어버려 우연히 혹은 실수로 여러 줄에 걸치는 명령을
입력할 때가 종종 있다. 이 경우 물론 mysql은 입력을 더 기다린다:

mysql> SELECT USER()
->

이럴 때는 mysql은 세미콜론을 기다리고 있는 것이다(여러분은 명령을 제대로
완전히 다 입력했다고 생각하지만 mysql은 그렇지 않다. 세미콜론이 빠졌기
때문이다). 프롬프트가 바뀐것을 눈치 채지 못한다면 결과를 기다리며 한참
동안의 시간을 낭비할 수도 있다. 세미콜론을 쳐 주어 명령을 완성하면
실행결과를 볼수있을 것이다:

mysql> SELECT USER()
-> ;
+--------------------+
| USER() |
+--------------------+
| joesmith@localhost |
+--------------------+

'>와 ">는 문자열을 모으는 중에 나타나는 프롬프트이다. MySQL에서는 문자들을
' 나 " 로 둘러싸면 문자열이 된다(예를 들면 'hello', "goodbye"등이다). 또한
여러 줄에 걸쳐 문자열을 입력할 수도 있다.'> 나 "> 프롬프트가 나타나면 이것은
'나 "로 시작하는 문자열을 포함하는 명령어를 쳐 넣었으나 닫는 ' 나 " 를 아직
쳐 넣지 않았다는 것을 의미하는 것이다. 여러 줄에 걸쳐 문자열을 입력할 때는
상관없다. 하지만 문자열을 여러 줄에 입력하고자 하는 경우가 얼마나 될까?
그다지 많지 않다. 대부분의 경우, '> 나 "> 프롬프트는 닫는 ' 나 " 를
빼먹었다고 알려주는 의미일 것이다. 예를 들면 다음과 같다.

mysql> SELECT * FROM my_table WHERE name = "Smith AND age < 30;
">

위와 같은 SELECT 문을 입력하고 엔터키를 치고 결과를 기다린다 해도 아무 결과도
볼 수 없을 것이다. "왜 아무 반응도 없는 것일까?"라고 이상하게 생각하지 말고
"> 프롬프트가 나타내는 의미를 생각해 보자. 문자열을 닫는 인용 부호를 빼먹었다는
것을 알리고 있다. 사실 위의 문장은 잘못이 있다. "Smith 다음에 "를 빼먹은 것이다.

자, 어떻게 해야 할까? 가장 간단한 방법은 명령을 취소하는 것이다. 그러나 간단히
\c를 칠수는 없다. 왜냐하면 \c도 "를 입력하기 전까지는 문자열의 일부로 취급을
받을 것이기 때문이다. 대신 "\c를 입력하면 된다:

mysql> SELECT * FROM my_table WHERE name = "Smith AND age < 30;
"> "\c
mysql>

프롬프트가 mysql>로 되돌려졌다. 물론 이것은 "새 명령어 실행 준비 완료"의
뜻이다.

'>와 ">가 의미하는 바를 기억하는 것은 중요하다. 잘못하여 닫는 인용 부호을
빼먹었을 때 계속 입력하는 것들은 모두 무시되는 듯하게 보이기 때문이다(여기에는
QUIT도 포함된다). 현재 명령을 취소하기 전에 닫는 인용부호를 꼭 써야한다는 것을
모르면 이것은 매우 혼동스러운 일일 것이다.


3. 데이터 베이스 만들고 사용하기

명령어 입력 방법을 알았으니 데이터베이스를 만들고 사용해 볼 때가 되었다.

집에서 애완동물을 키운다고 가정해 보자. 애완동물 각각에 대해서 여러가지 정보를
두고 유지하고 싶을 것이다. 데이터베이스를 만들고 그 안에 테이블을 만들어서
여기에 원하는 데이터를 넣어두면 된다. 그렇게 하면 테이블에서 자료를 가져와서
애완동물에 대한 여러 가지 정보들을 알아 낼 수 있다. 이 절에서는 이러한 것들을
포함하여 다음과 같은 사항들을 다루어 본다:

● 데이터베이스 만들기
● 테이블 만들기
● 테이블에 자료 넣기
● 테이블에서 자료 빼 내기
● 여러개의 테이블 사용하기

데이터베이스 이름을 menagerie('동물원'이라는 뜻이다)라고 짓자. menagerie
데이터베이스는 매우 간단하나 실제 생활에서도 간단한 데이터베이스를 사용하는
경우가 있다. 예를 들면 지금 만들고자 하는 데이터베이스를 가축을 사육하는
농부나 애완동물의 치료 기록을 남겨두어야 하는 수의사에 의해 사용될 수 있다.

SHOW 문을 사용하여 현재 서버가 유지중인 데이터베이스 목록을 볼 수 있다:

mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
| mysql |
| test |
| tmp |
+----------+

실제 목록은 위와 다를 수 있다. 하지만 mysql, test 데이터베이스는 항상 볼수있을
것이다. mysql 데이터베이스는 사용자 접근 권한 정보를 갖고 있는 중요한
데이터베이스이다. test는 말 그대로 연습하기 위해 있는 데이터베이스다. test
데이터베이스가 있다면 다음처럼 해서 사용할 수 있다:

mysql> USE test
Database changed

QUIT처럼 USE 문은 세미콜론이 필요하지 않다는 것을 기억하자(세미콜론으로 끝내도
상관없다. 그냥 간단하게 모든 문을 세미콜론으로 끝낸다고 기억해 두는 것도 좋다).
USE 문은 또한 한 줄에 기술해야 한다는 것도 반드시 기억하자.

test 데이터베이스에 접근할 수 있으면 이것을 사용할 수 있다. 하지만 동일한
데이터베이스(이 경우엔 test)에 접근할 수 있는 사람이 여러 사람이라면 여러분이
만들어 놓은 어떤 자료라도 다른 사람에 의해 접근이 가능하다. 이것은 삭제 및
변경될 소지가 있다는 말이다. 그래서 MySQL 관리자에게 여러분만의 데이터베이스를
사용할 권한을 달라고 요청해야 한다. 여기서는 menagerie라고 하자.
관리자는 다음과 같은 명령문을 실행할 필요가 있다:

mysql> GRANT ALL ON menagerie.* TO your_mysql_name;

your_mysql_name은 물론 허락해 줄 MySQL 계정명으로 대치해야 한다.


3.1 데이터베이스 만들고 선택하기

관리자가 접근 권한을 설정할 때 데이터베이스를 만들어 주었다면 그것을 그냥
사용하면 된다. 그렇지 않으면 다음처럼 하여 손수 여러분이 만들어 주면 된다:

mysql> CREATE DATABASE menagerie;

유닉스에서는 데이터베이스 이름은 대소문자를 구별한다(SQL 키워드는 그렇지 않다).
따라서 데이터베이스 이름을 항상 'menagerie'로 해야지 Menagerie, MENAGERIE,
meNaGerIE같은 것은 안된다. 테이블 이름도 마찬가지로 대소문자를 구분한다.

데이터베이스를 만들었다고 해서 사용하겠다고 알리는 것은 아니다.
명시적으로 사용하겠다고 해주어야 한다:

mysql> USE menagerie
Database changed

데이터베이스는 한번만 만들면 되지만 사용할 때마다 use 문을 이용하여 사용할
데이터베이스를 선택해야 한다. 당연한 논리가 아닐까? 다른 방법으로는 mysql을
시작할 때 데이터베이스 이름을 써 주어도 된다:

shell> mysql -h host -u user -p menagerie
Enter password: ********

여기서 menagerie가 패스워드는 아니다. 혼동하지 마라. 패스워드를 쓰려면 공백없이
바로 -p 뒤에 붙여 써 주어야 한다(역자주: 하지만 이 방법은 보안상 바람직한
방법이 절대 아닙니다. 패스워드가 글자그대로 화면에 보이기 때문입니다. 누가 어깨
너머로 보고있다면 어떻게 할 것인가요? 패스워드가 글자그대로 화면에 써진다는
것은 정말 위험한 것입니다. 현명한 관리자 및 사용자라면 -p 뒤에 패스워드를
적어 주는 "짓"은 하지 않을 것입니다. MySQL 개발자들은 왜 이렇게 했는지..).
패스워드가 아니라 사용할 데이터베이스 이름이다.


3.2 테이블 만들기

이전 절에서 본 것 처럼 데이터베이스를 만드는 것은 쉽다. 만들고 난 직후에는
다음 처럼

mysql> SHOW TABLES;
Empty set (0.00 sec)

데이터베이스는 비어 있다. 당연하다. 이제 막 만들었는데 들어있는 것이 있을 리
없다.

SHOW TABLES; 문은 선택된 데이터베이스에 있는 테이블을 보이는 명령이다.

테이블을 만드는 것은 정말 쉽다. 데이타베이스를 만들 듯, CREATE 문으로 만들면
된다. 잠시뒤에 알아 보자.

정말로 중요하고 어렵게 느껴지는 것은 데이터베이스를 어떻게 설계할 것인가이다.
어떤 테이블이 필요하고 이 안에 무슨 자료들을 넣어야 할지를 생각해야 한다.

여기서의 예에서는 각 애완 동물마다 한 개의 레코드를 두어야 할 것이다. pet
테이블이라고 이름 짓자. 각 테이블에는 애완 동물의 이름, 소유주(식구 이름이 될
것이다), 종, 성(암컷인지 수컷인지) 등등의 정보를 입력하고 싶을 것이다.

나이는? 나이도 필요할 것 같지만 시간에 따라 변하는 것이 나이이므로 나이에 대한
정보를 자주 갱신해 주어야 할 것이다. 보다 나은 방법을 강구해야 한다. 이런
상황을 미리 염두에 두고 설계해야 한다는 것이 데이터베이스 설계시 겪는 어려움이
아닐까 생각한다. 나이는 시간에 따라 변하므로 출생일을 기록해 두고 현재 날짜와의
차이로부터 계산하면 좋을 것이다. MySQL은 몇가지 산술 루틴을 제공하므로 이것은
어려운 일이 아니다. 나이대신 출생일을 기록해 두는 것은 다음 두가지 잇점이 있다:

● 다가오는 애완 동물의 생일을 미리 알려주는 일에 사용할 수 있다(동물에게
생일이라... 비현실적인 것 같지만, 이것은 다른 관점에서 생각해 볼 수 있다.
여러분의 고객의 생일은 어떤가? 언제 생일 축하카드를 보내야 하는지 알 필요가
있지 않은가?).

● 오늘 날짜 말고 다른 날짜를 기준으로도 나이를 계산할 수 있다. 예를 들어
사망일을 기록해 놓으면 애완 동물의 수명을 알 수 있을 것이다.

애완 동물에 대한 정보로서 다른 것들도 생각할 수 있겠지만 이정도로 해 두자.
충분하다.

CREATE TABLE 문으로 테이블을 만들 수 있다:

mysql> CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20),
-> species VARCHAR(20), sex CHAR(2), birth DATE, death DATE);

CREATE TABLE 다음에 테이블 이름을 써 주고 괄호 안에 열의 이름과 그 열의 자료형
을 한짝으로 하여 쉼표로 구분하여 열거해 주면 된다. name, owner, species, sex,
birth등이 열의 이름이며, VARCHAR(20), CHAR(2), DATE가 자료형이다. 자료형이란
말 그대로 자료의 형태이다. 자료는 문자열일 수 있고, 날짜일 수도 있고, 숫자일
수도 있다.

다음 표와 같은 테이블이 만들어진다:

pet TABLE
열 1열 2열 3열 4열 5열 6열
열이름 name owner species sex birth death


어떻게 자료를 입력하느냐에 따라 다르겠지만 진돗개 "용감이"의 경우 다음처럼 될
수 있다.

name owner species sex birth death
-------------------------------------------
용감이 홍길동 개 수컷 1998-3-4 NULL


VARCHAR는 길이가 변하는 문자열에 사용한다. 이름, 소유주, 종은 길이가 고정적이지
않은 문자열을 그 자료형으로 할 때 적당할 것이다. VARCHAR 형의 열들에 대해,
길이는 반드시 모두 같은 필요도 없고 20으로 고정될 필요도 없다. 1에서 255사이의
길이를 가질 수 있다. 적당하게 잡아주면 된다(나중에 ALTER TABLE 문으로 조정할
수도 있다). 테이블을 만들었으니 데이터베이스내 테이블 목록에 추가되었는가
확인하자:

mysql> SHOW TABLES;
+--------------------+
|Tables in menagerie |
+--------------------+
| pet |
+--------------------+

테이블이 명시한대로 만들어졌는지 확인하기 위해서는 DESCRIBE 문을 사용한다:

mysql> DESCRIBE pet;
+---------+-------------+-----+-----+---------+------+
| Field | Type | Null| Key | Default |Extra |
+---------+-------------+-----+-----+---------+------+
| name | varchar(20) | YES | | NULL | |
+---------+-------------+-----+-----+---------+------+
| owner | varchar(20) | YES | | NULL | |
+---------+-------------+-----+-----+---------+------+
| species | varchar(20) | YES | | NULL | |
+---------+-------------+-----+-----+---------+------+
| sex | char(2) | YES | | NULL | |
+---------+-------------+-----+-----+---------+------+
| birth | date | YES | | NULL | |
+---------+-------------+-----+-----+---------+------+
| death | date | YES | | NULL | |
+---------+-------------+-----+-----+---------+------+

Filed 부분과 Type 부분을 보고 열의 이름과 자료형을 확인하자. DESCRIBE는
언제든지 사용할 수 있다. 테이블 내의 열의 이름 및 자료형을 잊었을 때 사용하면
유용하다.

3.3 테이블에 자료를 넣어 보자.

테이블을 만든 후에는 테이블에 자료를 넣어야 한다. LOAD DATA 혹은 INSERT 문을
사용하면 된다.

애완동물 자료가 다음과 같다고 가정하자(MySQL은 YYYY-MM-DD 형식의 날짜 포맷을
요구한다).

name owner species sex birth death
-------------------------------------------------------------
Fluffy Harold cat f 1993-02-04
Claws Gwen cat m 1994-03-17
Buffy Harold dog f 1989-05-13
Fang Benny dog m 1990-08-27
Bowser Dianne dog m 1998-08-31 1995-07-29
Chirpy Gwen bird f 1998-09-11
Whistler Gwen bird 1997-12-09
Slim Benny snake m 1996-04-29

여러분은 빈 테이블에서 시작하므로 미리 파일에 각 동물에 대한 자료를 적어 두고
파일에서 읽어서 테이블을 채우면 좋을 것이다.

pet.txt라는 파일(파일이름은 아무것이든 상관없다)에 한 줄에 하나의 레코드를
기록하면 된다. 다음처럼:

# cat pet.txt
Fluffy Harold cat f 1993-02-04
-이후 생략-

열의 값들은 탭키 하나로 구분하며 CREATE TABLE 문에 명시한 순서대로 각 열의
값들을 열거해야 한다. 생략해도 되는 값(위에서 죽은 날짜와 성)에 대해서는
NULL값을 사용할 수 있다. 텍스트 파일에서 NULL값을 나타내기 위해서는 \N 이라고
써주면 된다. 예를 들어 Whistler의 예는 다음과 같을 것이다.

Whistler Gwen bird \N 1997-12-09 \N

pet.txt 파일을 로드하기 위해서는 다음처럼 LOAD DATA 문을 사용한다:

mysql> LOAD DATA LOCAL INFILE "pet.txt" INTO TABLE pet;

사용형식은 다음과 같다:

LOAD DATA LOCAL INFILE "파일이름" INTO TABLE 테이블이름;

한번에 한 개의 레코드를 추가하고자 할 때가 있을 것이다. CREATE TABLE 문을
사용하였을때 열거한 순서대로 각 열의 값을 적어 주면 된다. 물론 맞는
자료형으로 말이다:

mysql> INSERT INTO pet
-> VALUES('Puffball', 'Diane', 'hamster', 'f', '1999-03-30', NULL);

문자열 및 날짜를 작은 따옴표 ' 로 인용하였다. 위에서 언급한 NULL값도 입력할
수 있다(\N이라고 적으면 안된다).


3.4 테이블로부터 정보를 검색해 보자.

SELECT 문을 사용하면 된다. 일반 형식은 다음과 같다:

SELECT <검색대상> FROM <테이블> WHERE <검색조건>

<검색대상>은 무엇을 보고 싶은가를 알리는 것이다. 여러 열을 쉼표로 구분하여
적을 수 있으며 모든 열을 의미하는 *를 쓸 수도 있다. WHERE 부분은 생략할 수
있다. WHERE 문을 쓸 때는 검색조건을 써 준다. 검색조건을 만족하지 않는 행은
검색대상에서 제외된다.

3.4.1 모든 데이터를 검색하자.

가장 간단한 SELECT 문의 형태로 다음 처럼 사용할 수 있다:

mysql> SELECT * FROM pet;
+----------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+--------+---------+------+------------+------------+
| Fluffy | Harold | cat | f | 1993-02-04 | NULL |
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
| Fang | Benny | dog | m | 1990-08-27 | NULL |
| Bowser | Diane | dog | m | 1998-08-31 | 1995-07-29 |
| Chirpy | Gwen | bird | f | 1998-09-11 | NULL |
| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |
| Slim | Benny | snake | m | 1996-04-29 | NULL |
| Puffball | Diane | hamster | f | 1999-03-30 | NULL |
+----------+--------+---------+------+------------+------------+

이런 식으로 SELECT문을 사용하는 것은 테이블의 전체 정보를 보고자 할 때 유용하다.
방금 막 초기 데이터 뭉치를 올렸을 때 제대로 올려졌는지 확인코자 사용할 수 있다.
사람 사는 일이 그렇듯, 방금 본 결과에는 잘못된 것이 있다: Bower의 출생일자가
사망일자보다 늦다. 죽은 뒤에 태어났다?! 확인해 보니 birth는 1989-08-31이
되어야 함을 알 수 있었다고 하면 이를 어떻게 고칠까?

두가지 방법을 사용할 수 있다:

● 파일 pet.txt를 편집하여 수정한다. 테이블을 비운후 pet.txt에서 다시 읽어
들인다:

mysql> DELETE FROM pet;
mysql> LOAD DATA LOCAL INFILE "pet.txt" INTO TABLE pet;

하지만 이렇게 하면 3.3절에서 개별적으로 insert문을 이용하여 입력한 Puffball에
대해서 다시 입력해야 한다. 더 간단하고 바람직한 방법은?

● 잘못된 곳만 수정한다. UPDATE 문을 사용한다:

mysql> UPDATE pet SET birth="1989-08-31" WHERE name="Bowser";

위에서 볼 수 있듯이, 전체 테이블 내용을 보는 것은 쉽다. 그러나 보통 이렇게
하지는 않는다. 테이블 크기가 커지면 어떻게 할 것인가? 어떤 자료들을 검색할 때
그 많은 것을 일일이 다 볼것인가? 대신 특별한 조건을 만족하는 자료들만 뽑아서
보길 원할 것이다.

3.4.2 주어진 조건에 맞는 특정 행만을 검색해 보자.

여러분은 테이블에서 특별한 행들만 뽑아낼 수 있다. 예를 들어 Bower의 생일이
정말로 바뀌었는가 확인하기 위해 Bower의 레코드만 뽑아낼 수 있다:

mysql> SELECT * FROM pet WHERE name = "Bower";
+--------+-------+---------+------+------------+-----------+
| name | owner | species | sex | birth | death |
+--------+-------+---------+------+------------+-----------+
| Bowser | Diane | dog | m |1989-08-31 |1995-07-29 |
+--------+-------+---------+------+------------+-----------+

birth 열의 값이 1998년이 아닌 1989년으로 올바르게 수정되었음을 확인할 수 있다.

문자열 비교는 대소문자를 무시하는 비교다. 따라서 "bowser", "BOWSER" 등은 같은
문자열을 의미한다(위에서는 "Bowser"를 사용했다).

어떤 열에 대해서도 조건을 명시해 줄 수 있다. 예를 들어 1998년 이후에 태어난
동물을 알고 싶다면 birth 열을 대상으로 검사하면 된다:

mysql> SELECT * FROM pet WHERE birth >= "1998-1-1"
+----------+-------+---------+------+-----------+------+
| name | owner | species | sex | birth |death |
+----------+-------+---------+------+-----------+------+
| Chirp y | Gwen | bird | f |1998-09-11 | NULL |
| Puffball | Diane | hamster | f |1999-03-30 | NULL |
+----------+-------+---------+------+-----------+------+

조건을 조합할 수 도 있다:

mysql> SELECT * FROM pet WHERE species = "dog" AND sex = "f";
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Buffy | Harold | dog | f |1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+

위의 예는 개이면서 수컷인 동물을 검색하는 것이다.

위에서는 AND를 사용하였지만 OR를 사용할 수도 있다:

mysql> SELECT * FROM pet WHERE species = "snake" OR species = "bird";
+----------+-------+---------+------+-----------+-------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+-----------+-------+
| Chirpy | Gwen | bird | f |1998-09-11 | NULL |
| Whistler | Gwen | bird |NULL |1997-12-09 | NULL |
| Slim | Benny | snake | m |1996-04-29 | NULL |
+----------+-------+---------+------+-----------+-------+

AND와 OR를 섞어서 사용할 수 있다. 이렇게 할 때는 그룹지어지는 조건들을 괄호로
묶는 것이 좋다:

mysql> SELECT * FROM pet WHERE (species = "cat" AND sex = "m")
-> OR (species = "dog" AND sex = "f");
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+

3.4.3 특정한 열 선택하기

테이블에서 한행 전체를 보기 보다는 "관심 거리" 열들만 보고 싶다면 보고자 하는
열 이름을 다음처럼 사용하면 된다(아래 예는 name, birth열을 보고 싶은 경우이다):

mysql> SELECT name, birth FROM pet;
+----------+------------+
| name | birth |
+----------+------------+
| Fluffy | 1993-02-04 |
| Claws | 1994-03-17 |
| Buffy | 1989-05-13 |
| Fang | 1990-08-27 |
| Bowser | 1989-08-31 |
| Chirpy | 1998-09-11 |
| Whistler | 1997-12-09 |
| Slim | 1996-04-29 |
| Puffball | 1999-03-30 |
+----------+------------+

소유주만 보고자 할 때:
mysql> SELECT owner FROM pet;
+--------+
| owner |
+--------+
| Harold |
| Gwen |
| Harold |
| Benny |
| Diane |
| Gwen |
| Gwen |
| Benny |
| Diane |
+--------+

하지만 중복된 행이 있다. 중복된 행을 없애 보자:

mysql> SELECT DISTINCT owner FROM pet;
+--------+
| owner |
+--------+
| Benny |
| Diane |
| Gwen |
| Harold |
+--------+

DISTINCT 키워드를 사용하면 된다.

다음 처럼 열의 이름을 명시할 뿐만아니라 WHERE 절을 사용하여 조건을
추가함으로써 행의 선택과 열의 선택을 조합할 수 있다. 예를 들어 개와 고양이에
대해서만 이름, 종, 생일을 알고자 할 때 다음 처럼 SELECT문을 사용할 수 있다:

mysql> SELECT name, species, birth FROM pet
-> WHERE species = "dog" OR species = "cat";
+--------+---------+------------+
| name | species | birth |
+--------+---------+------------+
| Fluffy | cat |1993-02-04 |
| Claws | cat |1994-03-17 |
| Buffy | dog |1989-05-13 |
| Fang | dog |1990-08-27 |
| Bowser | dog |1989-08-31 |
+--------+---------+------------+

3.4.4 행 정열하기

지금까지 보인 예에서는 결과가 전혀 정렬되어 있지 않았음을 알 수 있을 것이다.
결과가 정렬된다면 원하는 자료를 훨씬 쉽게 알아볼 수 있다. 정렬하기 위해서는
ORDER BY 절을 사용하면 된다. 아래는 생일을 기준으로 정렬한 것이다.

mysql> SELECT name, birth FROM pet ORDER BY birth;
+----------+------------+
| name | birth |
+----------+------------+
| Buffy | 1989-05-13 |
| Bowser | 1989-08-31 |
| Fang | 1990-08-27 |
| Fluffy | 1993-02-04 |
| Claws | 1994-03-17 |
| Slim | 1996-04-29 |
| Whistler | 1997-12-09 |
| Chirpy | 1998-09-11 |
| Puffball | 1999-03-30 |
+----------+------------+

역순으로 정렬하려면 DESC 키워드를 열 이름 뒤에 적어준다:

mysql> SELECT name, birth FROM pet ORDER BY birth DESC;
+----------+------------+
| name | birth |
+----------+------------+
| Puffball | 1999-03-30 |
| Chirpy | 1998-09-11 |
| Whistler | 1997-12-09 |
| Slim | 1996-04-29 |
| Claws | 1994-03-17 |
| Fluffy | 1993-02-04 |
| Fang | 1990-08-27 |
| Bowser | 1989-08-31 |
| Buffy | 1989-05-13 |
+----------+------------+

하나의 열에 대해서만이 아니라 여러 열에 대해서도 정렬할 수 있다. 예를 들어
먼저 동물 이름으로 정렬하고 각 동물에 대해 생일 기준으로 정렬하되 가장 어린
것(가장 늦게 태어난 것; 역순 정렬)이 먼저 오게 하려면 다음처럼 한다:

mysql> SELECT name, species, birth FROM pet ORDER BY species, birth DESC;
+----------+---------+-----------+
| name | species | birth |
+----------+---------+-----------+
| Chirpy | bird |1998-09-11 |
| Whistler | bird |1997-12-09 |
| Claws | cat |1994-03-17 |
| Fluffy | cat |1993-02-04 |
| Fang | dog |1990-08-27 |
| Bowser | dog |1989-08-31 |
| Buffy | dog |1989-05-13 |
| Puffball | hamster |1999-03-30 |
| Slim | snake |1996-04-29 |
+----------+---------+-----------+

DESC 키워드는 바로 그 앞의 열 이름(birth)에만 적용된다는 것을 주의하라.
species는 여전히 오름차순으로 정렬된다.

3.4.5 날짜 계산

MySQL은 날짜를 다루는 몇가지 함수를 제공해 준다.

애완 동물의 나이가 얼마나 되는지 계산하려면 오늘 날짜와 출생시 날짜를 구하고,
두 날짜를 일수로 환산한 후, 그 차를 연간 일수 즉 365일로 나누어 주면 될 것이다:

mysql> SELECT name, (TO_DAYS(NOW())-TO_DAYS(birth))/365 FROM pet;
+----------+-------------------------------------------+
| name | (TO_DAYS(NOW())-TO_DAYS(birth))/365 |
+----------+-------------------------------------------+
| Fluffy | 6.15 |
| Claws | 5.04 |
| Buffy | 9.88 |
| Fang | 8.59 |
| Bowser | 9.58 |
| Chirpy | 0.55 |
| Whistler | 1.30 |
| Slim | 2.92 |
| Puffball | 0.00 |
+----------+-------------------------------------------+

TO_DAYS(NOW())은 지금까지의 날수를, TO_DAYS(birth)은 생년월일까지의 날수를
의미한다.

여기서 두가지 사항을 개선해 보자. 결과가 이름 혹은 나이 순으로 정렬되었으면
좋겠고, 나이에 해당하는 라벨명을 표현식 그대로 쓰는것보다는 "age"같은 것으로
하는 것이 좋을 것이다:

mysql> SELECT name, (TO_DAYS(NOW())-TO_DAYS(birth))/365 AS age
-> FROM pet ORDER BY name;

나이순으로 정렬하려면 ORDER BY name 대신 ORDER BY age로 써 주면 된다.

사망시의 나이도 비슷한 방법으로 알아 낼 수 있다:

mysql> SELECT name, (TO_DAYS(death)-TO_DAYS(birth))/365 AS age
-> FROM pet WHERE death IS NOT NULL ORDER BY age;

NOW()대신 death를 사용하면 된다. 여기서 아직 죽지 않은 동물의 수명을 조사한다는
것은 무의미하기 때문에 death 필드가 NULL이 아닌 경우를 조건으로 해 주었음을
주의하자. 조심할 것은 'death IS NOT NULL' 처럼 조건을 주어야 한다.
death != NULL 처럼 주어서는 안된다. NULL값에 비교 연산자를 적용할 수 없다.
나중에 이 문제는 다시 다룰 것이다.

다음 달에 생일인 동물을 알려면 어떻게 해야 할까? 이러한 문제를 위해 MySQL은
날짜에서 연도나, 달을 계산하는 함수를 제공한다: YEAR(), MONTH(), DAY().MONTH()
예를 통해 알아 보자:

mysql> SELECT name, birth, MONTH(birth) FROM pet;
+----------+------------+--------------+
| name | birth | MONTH(birth) |
+----------+------------+--------------+
| Fluffy | 1993-02-04 | 2 |
| Claws | 1994-03-17 | 3 |
| Buffy | 1989-05-13 | 5 |
| Fang | 1990-08-27 | 8 |
| Bowser | 1989-08-31 | 8 |
| Chirpy | 1998-09-11 | 9 |
| Whistler | 1997-12-09 | 12 |
| Slim | 1996-04-29 | 4 |
| Puffball | 1999-03-30 | 3 |
+----------+------------+--------------+

MONTH는 달에 해당하는 수를 반환해 주며, 물론 그 범위는 1에서 12까지이다.
다음달을 나태내기 위해서는 1을 더한 달을 명시해주면 된다:

mysql> SELECT name, birth FROM pet WHERE MONTH(birth) = 10;

그런데 문제가 있다. 12월인 경우 13을 명시해 주어야 하나? 13월이란 없다.
현재 달이 몇월이든지 상관없도록 새로운 조건식을 생각해 내야 한다. 여기에
두가지를 소개한다:

● MONTH(DATE_ADD(NOW(), INTERVAL 1 MONTH));
NOW()는 현재 날짜 및 시간을 반환해 준다. 여기에 1달이라는 기간을 더하고
달로 바꾸면 해결된다.

● MOD(MONTH(NOW()), 12) + 1;
MOD는 어떤 수를 다른 수로 나눈 나머지 값을 반환하는 함수이다. 첫번째 인자를
두번째 인자로 나눈 결과를 반환한다. 여기서는 현재 달 MONTH(NOW())를 12로
나눈 뒤 다음 달을 나타내기 위해 1을 더해 준다. 이번 달이 12월이라면 12로 나눈
나머지가 0이므로 여기에 1을 더해 다음달 1월을 나타내줄 수 있다.

완전한 SQL문은 각각 다음과 같다:

mysql> SELECT name, birth FROM pet
-> WHERE MONTH(birth) = MONTH(DATE_ADD(NOW(), INTERVAL 1 MONTH));

mysql> SELECT name, birth FROM pet
-> WHERE MONTH(birth) = MOD(MONTH(NOW()),12) + 1;

3.4.6 NULL 값에 대해

NULL값은 특별한 값이다. 익숙해질 때까지 혼동될 것이다. 개념적으로 NULL이
의미하는 바는 "빠진, 빼먹은 값", "아직 정해지지 않은 불확정 값"을 의미한다.
이것은 다른 값들과는 다르게 취급된다. NULL에는 산술 비교 연산을 수행할 수 없다.
어떤 값과 NULL값을 =, <, !=을 이용하여 비교하는 것은 의미가 없다. 불확정 값을
어떻게 확정된 값과 비교할 수 있을 것인가? 다음을 보라:

mysql> SELECT 1 = NULL, 1 != NULL, 1 < NULL, 1 > NULL;
+----------+-----------+----------+----------+
|1 = NULL |1 != NULL |1 < NULL | 1 > NULL |
+----------+-----------+----------+----------+
| NULL | NULL | NULL | NULL |
+----------+-----------+----------+----------+

위에서 보듯 불확정값과 확정값과의 비교는 불확정값이 된다. 의미가 없다.
그러나 다음과 같이 하면 의미가 있다:

mysql> SELECT 1 IS NULL, 1 IS NOT NULL;
+-----------+---------------+
| 1 IS NULL | 1 IS NOT NULL |
+-----------+---------------+
| 0 | 1 |
+-----------+---------------+

MySQL에서 거짓 값은 0으로 참값은 1로 나타낸다.

3.4.7 패턴 일치

패턴 일치 기능은 매우 유용한 기능이다. 보다 빠르고 정교하게 원하는 조건을
명세하여 검색할 수 있게 해주는 기능이기 때문이다.

MySQL은 표준 SQL 패턴 뿐만아니라 유닉스에서 사용하는 정규 표현식에 해당하는
패턴 일치 기능도 지원한다.

SQL에서 _ 은 임의 한 문자를 의미하며, %는 임의의 수의 문자(0개의 문자를 포함)를
가르킨다. SQL 패턴은 대소문자를 비교하지 않는다. LIKE 이후에 패턴을 준다는 것을
기억 하자. 아래 예를 보라:

b로 시작하는 이름에 대해서 검색할 때:

mysql> SELECT * FROM pet WHERE name LIKE "b%";
+--------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+------------+
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+

fy로 끝나는 이름에 대해서 검색할 때:

mysql> SELECT * FROM pet WHERE name LIKE "%fy";
+--------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+-------+
| Fluffy | Harold | cat | f | 1993-02-04 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+--------+--------+---------+------+------------+-------+

w를 포함하는 이름을 검색할 때:

mysql> SELECT * FROM pet WHERE name LIKE "%w%";
+----------+-------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+------------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |
+----------+-------+---------+------+------------+------------+

정확하게 5개의 글자로 이루어진 이름에 대해서 검색할 때는?

mysql> SELECT * FROM pet WHERE name LIKE "_____";
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+

밑줄을 5개 적어 준다.

이젠 정규표현에 기반한 패턴일치에 대해 알아 보자.
----------------------------------------------------------------------
정규표현식에 사용되는 문자 | 설명
------------------------------|---------------------------------------
. | 문자 하나
* | 앞에 나온 문자의 0개 이상의 반복
^ | 문자열 처음
$ | 문자열 끝
[,] | 괄호안의 문자들에 일치
{,} | 반복을 나타낼 때. 예로 n번 반복할 때
| {n}으로 적는다.
----------------------------------------------------------------------


여기서 SQL 패턴은 전체 값과 일치해야 "일치한다"고 하지만 정규표현은 값의 어느
부분과 일치해도 "일치한다"고 단정한다는 것을 유의해야 한다. 예를 들어,

SELECT * FROM pet WHERE name REGEXP "ffy";



SELECT * FROM pet WHERE name LIKE "ffy";

는 전혀 다른 결과를 낳는다. 직접 입력하여 알아보기 바란다.

문자 a나 b나 c중 하나를 가르키는 표현은 [abc]이다. [a-c]처럼 범위를 주어서
표현할 수도 있다. 정규표현은 대소문자를 구별한다. 따라서 대문자든 소문자든
상관없이 알파벳 문자 하나를 가리키는 표현은 [a-zA-Z]로 해야 한다.

*는 0개 이상의 문자들이라고 했다. x* 는 x, xx, xxx ... 에 해당한다. [0-9]*는 7,
12, 345, 678등의 임의의 길이를 갖는 수를 나타낸다. ^abc는 abc로 시작하는 패턴을
abc$는 abc로 끝나는 문자열을 의미한다.

정규 표현식을 쓸 때는 LIKE대신 REGEXP을 사용한다.

예를 보며 익혀 보자.

이름이 소문자 b 혹은 대문자 B로 시작하는 조건으로 검색:

mysql> SELECT * FROM pet WHERE name REGEXP "^[bB]";
+--------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+------------+
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+

이름이 fy로 끝날 때($를 사용한다):

mysql> SELECT * FROM pet WHERE name REGEXP "fy$";
+--------+--------+---------+------+-----------+-------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+-----------+-------+
| Fluffy | Harold | cat | f |1993-02-04 | NULL |
| Buffy | Harold | dog | f |1989-05-13 | NULL |
+--------+--------+---------+------+-----------+-------+

정확하게 5개의 문자로 이름어진 값은 다음 정규 표현에 일치한다:

^.....$

이것은 반복 연산자를 이용하여 다음처럼 쓸 수도 있다.

^.{5}$


3.4.8 행수 세기

누가 어떤 애완 동물을 몇이나 소유했는지 어떻게 알아낼 수 있을까?

이에 대한 답으로 COUNT()함수를 사용하면 되며 적당하게 조건을 부여해 주면 된다.

mysql> SELECT COUNT(*) FROM pet;
+----------+
| COUNT(*) |
+----------+
| 9 |
+----------+

각 소유주가 소유한 애완동물의 수는 다음처럼 하면 확인할 수 있다:

mysql> SELECT owner, COUNT(*) FROM pet GROUP BY owner;
+--------+----------+
| owner | COUNT(*) |
+--------+----------+
| Benny | 2 |
| Diane | 2 |
| Gwen | 3 |
| Harold | 2 |
+--------+----------+

각 owner의 모든 레코드들을 한데 묶기 위해 GROUP BY 절을 사용한 것을 주목하라.
이렇게 하지 않으면 에러 메시지를 보게 될 것이다.

mysql> SELECT owner, COUNT(owner) FROM pet;
ERROR 1140 at line 1: Mixing of GROUP columns (MIN(),MAX(),COUNT()...)
with no GROUP columns is illegal if there is no GROUP BY clause

COUNT()와 GROUP BY는 데이터에 여러 모양으로 특성을 부여하는 데 쓸모가 있다.
다음 예제들도 참고하자:

각 종에 해당하는 동물의 수:

mysql> SELECT species, COUNT(*) FROM pet GROUP BY species;
+---------+----------+
| species | COUNT(*) |
+---------+----------+
| bird | 2 |
| cat | 2 |
| dog | 3 |
| hamster | 1 |
| snake | 1 |
+---------+----------+

성에 따른 동물의 수:

mysql> SELECT sex, COUNT(*) FROM pet GROUP BY sex;
+------+----------+
| sex | COUNT(*) |
+------+----------+
| NULL | 1 |
| f | 4 |
| m | 4 |
+------+----------+

NULL은 "값을 모름"의 의미이다.

종과 성에 따른 동물의 수:

mysql> SELECT species, sex, COUNT(*) FROM pet GROUP BY species, sex;
+---------+------+----------+
| species | sex |COUNT(*) |
+---------+------+----------+
| bird | NULL | 1 |
| bird | f | 1 |
| cat | f | 1 |
| cat | m | 1 |
| dog | f | 1 |
| dog | m | 2 |
| hamster | f | 1 |
| snake | m | 1 |
+---------+------+----------+

바로 위의 경우와는 달리, 특정한 동물에 대해서만 조사해볼 수도 있다. 개와
고양이의 경우에만 각 성에 대해 몇마리인지 조사해 보자:

mysql> SELECT species, sex, COUNT(*) FROM pet
-> WHERE species = "dog" OR species = "cat"
-> GROUP BY species, sex;
+---------+------+----------+
| species | sex | COUNT(*) |
+---------+------+----------+
| cat | f | 1 |
| cat | m | 1 |
| dog | f | 1 |
| dog | m | 2 |
+---------+------+----------+

3.5 테이블 여러개 사용하기

pet 테이블은 애완동물에 대한 정보를 갖고 있다. 수의사에 치료를 받으러 갔던
횟수나 새끼를 낳은 날짜 같은 사건들에 대한 다른 정보를 기록하고 싶다면
별도의 테이블이 필요할 것이다. 테이블은 다음과 같은 조건을 요구할 것이다:

● 해당 동물의 이름을 갖고 있어야 한다. 어떤 애완동물에게 일어난 사건인지
분별해야 하기 때문이다.
● 언제 일어난 일인지 알기 위해 날짜 정보가 필요하다.
● 어떤 사건인지 묘사해 둘 필요가 있다.
● 사건을 분류하려면 사건 유형을 나타내는 필드도 있으면 좋을 것이다.

이와 같은 조건을 생각하여, 다음처럼 테이블을 만들어 보자:

mysql> CREATE TABLE event (name VARCHAR(20), date DATE,
-> type VARCHAR(15), remark VARCHAR(255));

pet 테이블의 경우처럼 파일로부터 데이터를 테이블로 올리자. event.txt에
다음처럼 적혀 있다고 하자.

Fluffy 1995-05-15 litter 4 kittens, 3 female, 1 male
Buffy 1993-06-23 litter 5 puppies, 2 female, 3 male
Buffy 1994-06-19 litter 3 puppies, 3 female
Chirpy 1999-03-21 vet needed beak straightened
Slim 1997-08-03 vet broken rib
Bowser 1991-10-12 kennel
Fang 1991-10-12 kennel
Fang 1998-08-28 birthday Gave him a new chew toy
Claws 1998-03-17 birthday Gave him a new flea collar
Whistler 1998-12-09 birthday First birthday


다음처럼 테이블을 채우자:

mysql> LOAD DATA LOCAL INFILE "event.txt" INTO TABLE event;

지금까지 pet 테이블을 다루면서 배웠듯이 event 테이블에 대해 여러가지
질의를 해볼 수 있을 것이다. 하지만 정보가 불충분할 때는 어떻게 하는가?

새끼를 낳았을 때 어미의 나이를 알려면 어떻게 해야 하는가? event 테이블을
통해 언제 새끼를 낳았는지는 알 수 있지만 어미의 나이라든가, 소유주라든가 하는
것은 pet 테이블을 통해서 알아내야 한다. 따라서 SELECT 문을 사용할 때 두개의
테이블이 필요하다:

mysql> SELECT pet.name, (TO_DAYS(date) - TO_DAYS(birth))/365 AS age,
-> remark FROM pet, event
-> WHERE pet.name = event.name AND type = "litter";
+--------+------+-----------------------------+
| name | age | remark |
+--------+------+-----------------------------+
| Fluffy | 2.27 | 4 kittens, 3 female, 1 male |
| Buffy | 4.12 | 5 puppies, 2 female, 3 male |
| Buffy | 5.10 | 3 puppies, 3 female |
+--------+------+-----------------------------+

위의 예로부터 몇가지 알아두어야 할 사항이 있다:

● FROM 절에 사용할 테이블을 모두 적어 주어야 한다. 이것들 모두로부터의
정보가 필요하기 때문이다.
● 여러 테이블에서 정보를 뽑아 합할 때는 한 테이블의 레코드가 다른 테이블의
레코드와 어떻게 일치하는지 명시해 주어야 한다. 여기서는 두 테이블 모두 name
필드를 갖고 있으므로 이것을 이용하면 된다. 위에서 WHERE 절에
pet.name = event.name 조건을 줌으로써 두 개의 테이블의 같은 동물에 해당하는
레코드에 대해서 질의를 하게 된다. 서로 다르다면 의미가 없다.
● 두 테이블 모두 name 필드를 갖고 있으므로 어느 테이블에 속하는 필드인지를
구분하기 위해 <테이블이름>.<필드이름>의 형식으로 적어 주었다. 즉
테이블 이름과 필드 이름을 점으로 구분하여 적어 준다.

위에서 테이블은 서로 달랐다. 하지만 동일한 테이블에 대해서 위에서처럼 사용할
필요가 있을 때가 있다. 예를 들어 개의 수컷과 암컷을 짝지어 주려면 어떻게 해야
하는가? 동일한 테이블에 대해서 성이 같은지 다른지 검사해야 한다. 다음에 한
예를 든다:

mysql> SELECT p1.name, p1.sex, p2.name, p2.sex, p1.species
-> FROM pet AS p1, pet AS p2
-> WHERE p1.species = p2.species AND p1.sex = "f" AND p2.sex = "m";
+--------+------+--------+------+---------+
| name | sex | name | sex | species |
+--------+------+--------+------+---------+
| Fluffy | f | Claws | m | cat |
| Buffy | f | Fang | m | dog |
| Buffy | f | Bowser | m | dog |
+--------+------+--------+------+---------+


3.6 배치 모드(일괄 처리 모드)로 사용하기

지금까지는 대화식으로 사용하였다. 질의를 쳐 넣고 결과를 보는 식의 반복적인
작업이었다.

작업 내용 전부를 파일에 기술해 준 후 한꺼번에 처리할 수도 있다. 이렇게 하는
작업을 배치 작업이라고 한다는 것쯤은 알아 두자. 다음과 같은 식으로 사용한다:

shell> mysql < batch-file

작업 내용을 써 둔 파일 내용을 표준 입력으로 받으면 된다. 호스트명 및 사용자명,
패스워드를 입력할 필요가 있으면 추가로 써 준다:

shell> mysql -h host -u user -p < batch-file
Enter password: ********

여러분이 배치 모드에서 사용할 파일을 작성하는 것은 바로 스크립트를 작성하는
것이다.

기본 결과는 대화식으로 할 때와는 다르다. SELECT DISTINCT species FROM pet을
시켰을 때 대화식과 배치 모드에서의 결과를 보자. 내용은 같지만 출력 형식이
다르다.

대화식:
+---------+
| species |
+---------+
| bird |
| cat |
| dog |
| hamster |
| snake |
+---------+

배치 모드:
species
bird
cat
dog
hamster
snake

배치 모드에서도 대화 모드에서와 같은 형식으로의 출력을 원하면 mysql 실행시 -t
옵션을 주면 된다. 만약 실행되는 명령어도 출력에 포함하고 싶다면 -vvv를 붙여라.

그렇다면 무슨 이익이 있길래 배치 모드를 사용할까? 다음에 몇가지를 적어 두었다.

● 질의를 자주 한다면 스크립트로 만들어 두는 것이 실행할 때마다 매번 다시 쳐
넣어주는 수고를 없애 준다.
● 이미 작성한 스크립트를 수정하여 개선할 수 있고 새로운 스크립트를 작성할 수
있는 잇점이 있다.
● 여러 줄에 걸치는 매우 복잡한 질의를 수행할 때는 배치 모드가 적당할 것이다.
실수를 했을 때 대화모드라면 전부 다시 쳐넣어 주어야 한다. 배치 모드일때는
파일만 수정해 주면 된다. 하지만 MySQL은 readline 라이브러리(히스토리기능을
구현한 라이브러리)기능을 사용하므로 대화 모드일 때도 다시 명령어를 쳐 넣는
수고를 크게 덜 수는 있다.
● 출력 결과가 매우 많다면 배치모드로 실행시키고 페이저(일정한 페이지 줄수로
문서를 보여주는 프로그램을 통칭하는 명칭)를 통해 보면 좋을 것이다.
다음 처럼:

shell> mysqlk < batch-file | less

● 출력 결과를 다른 파일로 저장할 수 있다. 저장된 파일은 추가 작업의
출발점으로 활용될 수 있다.

shell> mysql < batch-file > mysql.out

● 작성한 스크립트를 다른 사람과 공유할 수 있다. 다른 사람도 여러분이 작성한
스크립트를 실행할 수 있으며 참고할 수 있다.
● 어떤 작업은 성격상 배치모드에서만 실행할 수 있다. 일정한 시간 간격으로 어떤
작업을 할 때는 cron을 이용하여 배치모드에서 처리할 수 밖에 없다.

'DataBase > MYSQL' 카테고리의 다른 글

My-SQL DB 자동 백업 스크립  (0) 2008.09.29
DB 다른 서버로 이전방법  (0) 2008.09.29
mysql 명령어 요약( db생성, user생성, db-user적용)  (0) 2008.09.29
MySQL 명령어 모음  (0) 2008.09.29

출처 : http://cafe.naver.com/solatech/174



** 하우투 솔라리스에서 퍼온 글 입니다. 
 
 
 
솔라리스의 1 sector 는 1 block 이고 512 bytes 입니다.  
 
가끔 fsck 를 시도시 다음과 같이 cannot read 라는 메세지와 함께 fsck 상태가  
멈추어 버리는 경우가 있습니다.  
이경우는 전혀 mount를 할수 없습니다.  
여러번 fsck를 시도해 보아도 같은 현상이 나오곤 합니다.  
 
다음은 fsck 시도시 위와 같은 현상이 나오는 예제 입니다.  
 
# fsck /dev/rdsk/c0t1d0s0  
** /dev/rdsk/c0t1d0s0  
** Last Mounted on /  
** Phase 1 - Check Blocks and Size  
 
CANNOT READ: BLK 2036256  
CONTINUE? y  
 
** Phase 2 - Check Pathnames  
** Phase 3 - Check Connectivity  
** Phase 4 - Check Reference Counts  
** Phase 5 - Check Cyl groups  
 
FREE BLK COUNT(S) WRONG IN SUPERBLK  
SALVAGE? y  
 
THE FOLLOWING SECTORS COULD NOT BE READ: 2036256 2036257 2036258 2036259  
 
fsck is incapable of fixing sector errors.  
 
fsck is incapable of of fixing sector erros 라는 메시지를 뿌리고 작업이 중단 되거나  
/var/adm/messages 파일에 다음과 같이 뿌려주는 경우도 있습니다.  
 
 
Error for command 'read(10)' Error Level: Retryable  
Requested Block 2422272, Error Block: 2422283  
Sense Key: Media Error  
Vendor 'SEAGATE':  
ASC = 0x11 (unrecovered read error), ASCQ = 0x0, FRU = 0x0  
 
 
위와 같은 현상이 나타나는 이유는 sector의 formating 정보의 손실이나 전기적  
현상에 의한 sector의 문제인 경우가 많습니다.  
 
 
대부분의 경우 이런 현상이 나오게 되면 newfs 하거나 format하여 사용하면 정상적으로 사용 할수 잇습니다.  
그러나 중요한 정보나 데이타가 있다면 newfs 나 format의 경우 모두 없어지게 됩니다.  
그래서 평소에 백업을 충실히 해두라는 말입니다...  
나중에 후회 하지 말구여...  
 
희망이 없는것은 아닙니다... 한번 해보자구여...  
 
 
에러현상은 다음과 같이 크게 SOFT ERROR과 HARD ERROR로 들수 있습니다.  
 
SOFT ERROR  
----------  
soft에러 발생시 데이타는 영향을 받는 블럭(Affacted block)은 영향을 받지않는(alternate block)으로  
이동하게 됩니다. 그리고 이 불안정한 블럭은 repaired되거나 flawed sector(손상된섹터)  
라는 꼬리표를 달게 됩니다.  
 
 
HARD ERROR  
----------  
하드웨어적인 에러는 디스크의 I/O나 SCSI의 문제일수도 있다..  
물리적 전기적 충격을 가하지 않았다면 디스크는 왠만해선 고장 나지 않는다.  
위의 soft error일 경우가 많은데 Hard error로 간주한다면  
여러분의 귀중한 데이타는 없어질지도 모릅니다.  
정말루 확실한 Hard error라고 판명이 되면 수리센타에 의뢰하는 것이 좋습니다.  
format명령어를 실행했을 경우 Hard error은 디스크타잎을 모르거나 인식이 되지 않는  
경우 입니다.  
 
그런데 디스크타잎과 정보는 정상적인데 fsck시 나타나는 현상이 생기면  
일단은 다음과 같이 해 봅시다...정말 몇천만원 짜리 데이타라면 중요하므로  
전문 복구센타에 의뢰하셔야지 제가 하는데로 하시다간 저만 나쁜놈 됩니다.  
그래도 밑져야 본전 중요한 데이타가 아니라면 일단 한번 해보시죠...  
혹시 압니까.. 제덕에 돈벌런지....ㅋㅋ  
 
 
자그럼 지금 부터 하는 내용을 잘 따라 하시면됩니다.  
 
 
format 명령어를 칩니다.  
 
증상이 나타나는 디스크의 번호를 선택 합니다.  
 
블럭에러가 하나인 것은 다음과 같은 예로 하시면 됩니다.  
 
일단은 error bolck number를 아셔야 합니다.  
 
예)  
 
# format  
AVAILABLE DISK SELECTIONS:  
0. c0t0d0 <IBM-DDYS-T18350M-SA2A cyl 14970 alt 2 hd 6 sec 399>  
/sbus@1f,0/SUNW,fas@e,8800000/sd@0,0  
1. c0t1d0 <SUN4.2G cyl 3880 alt 2 hd 16 sec 135>  
/sbus@1f,0/SUNW,fas@e,8800000/sd@1,0  
2. c0t2d0 <IBM-DCAS-34330-S65A cyl 8203 alt 2 hd 6 sec 171>  
/sbus@1f,0/SUNW,fas@e,8800000/sd@2,0  
3. c0t4d0 <IBM-DORS-32160-WA6A cyl 6701 alt 2 hd 5 sec 125>  
/sbus@1f,0/SUNW,fas@e,8800000/sd@4,0  
Specify disk (enter its number)[3]: 3 ----> block error가 난 디스크선택  
selecting c0t4d0  
[disk formatted]  
format> repair  
Enter absolute block number of defect: 4080544 ---> 에러 block number  
Ready to repair defect, continue? y  
(at this point, format will indicate how and if the block was repaired)  
format> q  
 
이런식으로 하시면 됩니다. 에러 블럭이 하나라면 위와 같은 식으로 하시면 되겠죠..  
그다음 raw device를 fsck 시켜 줍니다. 그럼 아무문제 없이 fsck될 것입니다.  
그담엔 mount 하시면 됩니다.... 성공하면 방명록에 고맙다는 리플 다시는거  
잊지마셈...  
 
 
자 그럼 두개 이상의 block error 을 reoair하려면 어떻게 하는지  
 
다음 예를 들어 봅니다.  
 
예)  
AVAILABLE DISK SELECTIONS:  
0. c0t0d0 <IBM-DDYS-T18350M-SA2A cyl 14970 alt 2 hd 6 sec 399>  
/sbus@1f,0/SUNW,fas@e,8800000/sd@0,0  
1. c0t1d0 <SUN4.2G cyl 3880 alt 2 hd 16 sec 135>  
/sbus@1f,0/SUNW,fas@e,8800000/sd@1,0  
2. c0t2d0 <IBM-DCAS-34330-S65A cyl 8203 alt 2 hd 6 sec 171>  
/sbus@1f,0/SUNW,fas@e,8800000/sd@2,0  
3. c0t4d0 <IBM-DORS-32160-WA6A cyl 6701 alt 2 hd 5 sec 125>  
/sbus@1f,0/SUNW,fas@e,8800000/sd@4,0  
Specify disk (enter its number)[3]: 3  
selecting c0t4d0  
[disk formatted]  
 
format> analyze  
 
analyze> setup  
analyze> setup  
Analyze entire disk[yes]? no  
Enter starting block number[0, 0/0/0]: 2036240  
Enter ending block number[2052287, 2035/13/7]: 2036270  
Loop continuously[no]? no  
Enter number of passes[2]: 1  
Repair defective blocks[yes]? yes  
Stop after first error[no]? no  
Use random bit patterns[no]? no  
Enter number of blocks per transfer[126, 0/2/0]: 1  
Verify media after formatting[yes]? yes  
Enable extended messages[no]? no  
Restore defect list[yes]? yes  
Restore disk label[yes]? yes  
 
analyze> read  
Ready to analyze (won't harm SunOS). This takes a long time,  
but is interruptible with CTRL-C. Continue? y  
 
pass 0  
 
Error during read: block 2036256 (0x5da1c0) (2003/5/3)  
Repairing soft error on 2036256 (2003/5/3)...ok.  
 
Error during read: block 2036257 (0x5da1c1) (2003/5/4)  
Repairing soft error on 2036257 (2003/5/3)...ok.  
 
Error during read: block 2036258 (0x5da1c2) (2003/5/5)  
Repairing soft error on 2036258 (2003/5/3)...ok.  
Error during read: block 2036259 (0x5da1c3) (2003/5/6)  
Repairing soft error on 2036259 (2003/5/3)...ok.  
 
2035/13/7  
 
Total of 4 defective blocks repaired.  
(0x5da1c0) (2003/5/3)  
(0x5da1c1) (2003/5/4)  
(0x5da1c2) (2003/5/5)  
(0x5da1c3) (2003/5/6)  
 
analyze> quit  
format> quit  





출처 : http://blog.naver.com/navy_han?Redirect=Log&logNo=70024449636



### 시스템 점검 및 장애복구 방법 ###

 

Hardware 점검

hoony[root:/#]format
nSearching for disks...done nAVAILABLE DISK SELECTIONS:       
0. c0t0d0 <SUN18G cyl 7506 alt 2 hd 19 sec 248>          
/sbus@1f,0/SUNW,fas@e,8800000/sd@0,0 n      
1. c0t1d0 <SUN18G cyl 7506 alt 2 hd 19 sec 248>         
/sbus@1f,0/SUNW,fas@e,8800000/sd@1,0

hoony[root:/#]iostat -En
c0t0d0          Soft Errors: 0 Hard Errors: 0 Transport Errors: 0
Vendor: SEAGATE  Product: ST39236LC        Revision: 0005 Serial No:
Size: 9.19GB <9185582592 bytes> n
Media Error: 0 Device Not Ready: 0 No Device: 0 Recoverable: 0
Illegal Request: 0 Predictive Failure Analysis: 0 n
c0t6d0          Soft Errors: 0 Hard Errors: 0 Transport Errors: 0
Vendor: TOSHIBA  Product: XM6201TASUN32XCD Revision: 1103 Serial No:
Size: 0.00GB <0 bytes> nMedia Error: 0 Device Not Ready: 0 No Device: 0 Recoverable: 0
n* -En option은 5.6 이상에서만 지원됨

 

LAN Port 점검

점검목적 nsystem 에 장착되어 있는 LAN card 의 Port 및 cable 의 연결상태를 점검하여
network의 장애 요소를 제거

hoony[root:/#]netstat -i
Name Mtu Net/Dest Address Ipkts Ierrs   Opkts      Oerrs Collis Queue
lo0 8232 loopback localhost 231473 0        231473   0       0       0
hme1 1500 ns ns 1450055 0        1296494  0       0       0
Ierrs : Input error ( 0.025% 까지는 정상 ), Oerrs : Output error( 0.025% 까지는 정상 )
Queue : 10% 까지는 정상.
* 시스템을 부팅한지 오래된 경우에는 맞지 않을 수 있음

Software 점검

hoony[root:/#]df -k
파일시스템                 K바이트         사용      가용    용량    설치지점
/dev/dsk/c0t0d0s0    6196234   5893082  241190    97%    /
/proc                                  0             0           0     0%    /proc
fd                                       0             0           0     0%    /dev/fd
mnttab                                0             0           0     0%    /etc/mnttab
swap                        2222704           24 2222680     1%    /var/run
/dev/dsk/c0t0d0s5     9136141  7682616 1362164    85%    /users1
/dev/dsk/c0t1d0s6   17413250 13630019 3609099    80%    /mnt
swap                        2223784        1104 2222680     1%    /tmp 
Core file 및 lost+found file 정리(find 명령어 사용)
90%이상 넘는 부분이 있을 시 일단 data 영역에서 필요 없는 파일들을 제거
core file 등과 같은 size 가 크고 불필요한 파일을 제거하여 90% 이하 수준으로 유지

 

Network 점검

점검목적 nNetwork를 구성하는 configuration file 과 table들을 점검하여 외부와의 서비스에
장애요소가 있는지 점검

점검방법 nNetwork 관련 해당 파일 확인
system booting시에 network configuration이 정상적으로 설정됨을 점검
(/etc/hosts, /etc/hostname*,  /etc/inet/*)

현재 Network 환경 설정 확인
ifconfig –a 와 netstat –nr 명령어를 이용하여 network device 의 설정 및 routing table 이
정상인지 점검 nNetwork 외부 연동 확인

외부 system 과의 ping , telnet 여부 확인
snoop ,arp 로 protocol 이 정상인지 확인

 

Administration File 점검
hoony[root:/#]who -b 

       system boot   8월  9 15:55
hoony[root:/#]who -r 

       run-level 3   8월  9 15:55     3      0  S
/var/adm/message file중 WARNING , Error 가 포함되어 있는지  점검하여 과거와 현재
장애 component 의 교체 여부를 결정
hoony[root:/#]grep WAR /var/adm/messages*
hoony[root:/#]grep Err /var/adm/messages*
hoony[root:/#]grep panic /var/adm/messages*

 

계정관리 File 확인

/etc/passwd , /etc/shadow, /etc/group file들을 점검, 운영에 불필요한 계정이 있는지 확인
hoony[root:/#]more /etc/passwd
root:x:0:1:Super-User:/:/bin/ksh
daemon:x:1:1::/: nbin:x:2:2::/usr/bin:
sys:x:3:3::/:
… … …
listen:x:37:4:Network Admin:/usr/net/
ls: nnobody:x:60001:60001:Nobody:/:
noaccess:x:60002:60002:No Access User:/:
nobody4:x:65534:65534:SunOS 4.x Nobody:/:
* passwd 파일은 7개의 필드로 구성 
 (login ID : x : UID : GID : comment : home directory : login shell)

hoony[root:/etc/inet#]more /etc/shadow
root:1OTpM5zTYsnJ6:12660:7:49::::
daemon:NP:6445::::::
bin:NP:6445:::::: nsys:NP:6445::::::
… … … nlisten:MZu2Kz2foRU.g:::::::
nobody:NP:6445:::::: nnoaccess:NP:6445::::::
nobody4:NP:6445::::::
* shadow파일은 9개의 필드로 구성(password가 암호화되어 있는 file)
(login ID : passwd : lastchg : min : max : warn : inactive : expire : )

 

패스워드 정책 설정 값 확인
/etc/default/passwd file에 MAXWEEKS=4 , PASSLEGTH=6 으로
설정하여 4주마다 한번씩은 password를 변경하고, 6자리 이상으
로 하여 Password의 유출을 최대한 방지

주기적인 job 정상운용 여부 확인 ncron이 정상적으로 설정되어 있는지 crontab -l 로 확인
실행 후 log file 인 /var/cron/log or olog 를 점검하여 cron 수행시 nerror 발생 여부 확인

DISK I/O 사용율 niostat 혹은 vmstat 명령어를 사용하여 system disk 및 data disk 의 I/O
performance를 측정. solaris 8 일 경우 iostat –xnt option 을 사용하여
I/O 에 error 가 발생하는지를 점검
hoony[root:/etc#]iostat -xnt 2 100
extended device statistics       ---- errors ---
r/s    w/s   kr/s   kw/s wait actv wsvc_t asvc_t  %w  %b s/w h/w trn tot device
17.1   13.1   76.3   97.4  0.2  1.2    7.5   41.3   0  18   0   0   0   0 c0t0d0
0.0    0.0    1.2    0.0  0.0  0.0    0.0    5.7   0   0   0   0   0   0 c0t1d0
0.7    0.0    1.5    0.0  0.0  0.0   19.5   10.2   0   0   0   0   0   0 c0t6d0
0.0    0.0    0.0    0.0  0.0  0.0    0.0    0.6   0   0   0   0   0   0 hoony:vold(pid305)

 

Memory 및 swapping 사용율
sar 나 swap 명령어를 사용, 현재 free memory 값 점검 및 확인
vmstat 값에서 page 의 sr 이 값이 200 이 넘는 경우가 있는지를 점검
hoony[root:/etc#]swap –s
총: 39824k 바이트 할당 + 21152k 예약 = 60976k 사용, 2223800k 사용 가능
hoony[root:/etc#]vmstat 2 100
procs     memory            page            disk          faults      cpu
r b w   swap  free  re  mf pi po fr de sr s0 s1 s6 --   in   sy   cs us sy id
2 0 0 2208584 146352 2  18 71  0  0  0  0 30  0  1  0  411  282  138  1 25 74
0 0 0 2223728 157592 0   2  0  0  0  0  0  0  0  0  0  307   99   91  0  0 100
0 0 0 2223728 157592 0   0  0  0  0  0  0  0  0  0  0  304   81   86  0  0 100
0 0 0 2223728 157592 0   0  0  0  0  0  0  0  0  0  0  308   77   75  0  0 100
0 0 0 2223728 157592 0   0  0  0  0  0  0  0  0  0  0  305   86   86  0  0 100

 

Disk 장애
장애 유형 및 복구 절차
장애 현상
WARNING:/pci@1f,4000/scsi@3/sd@1,0(sd1):
Error for command: write     Error Level: Retryable
Requested Block: 90722224    Serial Number: 3HZ62CT3
Sense Key: Hardware Error nWARNING: /pci@1f,4000/scsi@3/sd@1,0(sd1):
SCSI transport failed: reason ‘reset’ : retrying command
WARNING: /pci@1f,4000/scsi@3/sd@1,0(sd1):
SCSI transport failed: reason ‘incomplete’ : retrying command
WARNING: /pci@1f,4000/scsi@3/sd@1,0(sd1):
Disk not responding to selection
장애 복구 절차
Hard disk 의 불량으로 hardware 교체. 같은 용도로 사용중인 양호한 장비의 disk로부터 데이터 copy or reinstall

장애 현상
정전이나 부적절한 방법으로 시스템 종료로 file system 이 깨졌을 경우
부팅 시 multi user 모드로 부팅되지 않을 수 있다.
장애 복구 절차
부팅 시 multi user 모드로 부팅 하지 못하고 single user 모드에서
멈췄을 때(maintenance) root 암호를 입력하여 single user 모드로 들어간다.
# fsck 를 실행
(주의) fsck –y 명령을 실행하면 진행되는 동안 inode를 삭제할 수 있기 때문에 복구가 안될 수도 있다.
fsck 명령 실행 시에는 –y 옵션을 빼고 실행할 것.

 

CPU 장애
장애 유형 및 복구 절차
장애 현상
panic[cpu0]/thread=0x3001fec0: BAD TRAP: cpu=0 type=0x31 rp=0x3001bb00 addr=0x0
mmu_fsr=0x0 nBAD TRAP occurred in module "sd" due to an illegal access to a user address.
sched: trap type = 0x31
pid=0, pc=0x601aa4b0, sp=0x0, tstate=0x3001bb9000000000, context=0x1e03
g1-g7: 0, 30002, 112c000000000000, 7fff, abb5d55900000000, 0, 3001bec0
장애 복구 절차
cpu panic 현상이 발생하면 /var/crash/hostname 디렉토리에 이미지 파일이 생기게 된다.
adb 유틸리티나 기타 방법으로 이미지 파일을 분석한 후 hardware교체 여부를 판단

Memory 장애
장애 유형 및 복구 절차
장애 현상
May 22 11:09:50 eprjdb2 SUNW,UltraSPARC-II: [ID 362078 kern.info] [AFT0] Corrected Memory Error
detected by CPU11, errID 0x001dd49c.d54e5a7b nMay 22 11:09:50 eprjdb2 SUNW,UltraSPARC-II: [ID 589262 kern.info]
[AFT0] errID 0x001dd49c.d54e5a7b Corrected Memory Error on Board 5 J3101 is Persistent
장애 복구 절차 n먼저 /var/adm/messages 파일에 발생된 메시지에서
CE (Correctable memory Error)인지 UE (Uncorrectable memory Error)
인지 판단하여 다음의 용어를 참조 하여 교체 여부를 판단한다.

Intermittent : data에 오류가 있어 다시 해당 word를 read할 시 error가
없는 경우로 memory module 교체는 필요 없다.
* Persistent  : data에 오류가 있어 다시 해당 word를 read할 시 또 오류가
있는 경우로 memory scrub operation으로 해당 bit를 fix를
수정한 경우로 한 module에서 계속적인 error가
(24시간 내 4번 이상) 없을 경우 memory 교체는 필요 없다.
* Sticky : persistent error로 bit를 수정한 이후에도 error가 fix되지 않는
경우로 이 error가 발생하면 즉시 memory를 교체해 주어야 한다

 

File System Full
Root, VAR 등의 File System이 Full
/ 화일시스템에 사용자가 임의로 만들어 준 디렉토리, 파일 여부 확인
/dev 디렉토리 밑에 일반 파일이 있는지 조사
# find /dev  -type f -exec ls -l {} \;
일반 파일이 있을 경우, 모두 삭제. 특히 테이프에 백업을 받을 경우에 사용자가 디바이스명을 잘못 지정하여,
테이프에 백업되지 않고 파일에 저장하는 경우가 있다.
시스템에 있는 core 화일을 제거

core 화일을 찾아 보려면 다음과 같은 명령어를 사용한다.
# find / -name core –print

core 화일을 찾아서 자동으로 지우려면 다음과 같은 명령어를 실행
# find / -name core -exec rm {} \; -print


/var 디렉토리 밑을 조사한다.
# du -sk /var/* | sort –nr
/var 밑에 있는 디렉토리 별로 그 서브 디렉토리까지 포함하여 KB단위로
크기를 출력. 정상적인 시스템에 문제가 될 디렉토리는 다음과 같다.
/var/adm, /var/mail, /var/log, /var/preserve, /var/spool
/var/adm/messages*, wtmp, wtmpx, pacct
시스템이 운용 중에 발생하는 메세지나 기타 정보들이 누적 보관되는 곳.
messages : 시스템에서 발생되는 메세지를 보관하는 파일
wtmp, wtmpx : 시스템에 접속한 사용자에 대한 정보
pacct : accounting 정보를 가지고 있는 파일
# cp /dev/null messages # cp /dev/null wtmp
# cp /dev/null wtmpx # cp /dev/null pacct

/var/mail
메일 데이터가 보관되는 곳(해당 사용자에게 그 메일을 정리하도록 권고)
※ 파일을 지울 때, 그 파일이 어떤 파일인지 숙지한 후에
지울 것인가 아닌가를 결정
/ 파일 시스템에 있는 1 MB 이상 되는 파일을 조사하여, 파일 크기순으로 sort하여 그 내용을 조사한다.
# find / -mount -size +1024k -ls > /tmp/find.list
# sort -nr +6 /tmp/find.list > /tmp/find.list.s
find.list.s 파일에서 비정상적인 큰 파일이 있는지 조사한다

 

[스크랩] Solaris 시스템 현황보기

Posted 2009. 2. 24. 18:55

[출처] Solaris 시스템 현황보기|작성자 튤립정원



#prtdiag -v | more : 시스템 상태 보기 (H/W 고장 여부 포함)

#prtconf    : instance 간략 보기

#psrinfo    : processor 간략 보기, 부팅 시간도 표시

#prstat      : process 상태 보기

#/usr/platform/`uname -i`/sbin/prtdiag -v

#showrev  : 모델 등

#iostat -nE: disk 등

 

 

#w           : uptime+whodo요약

#uptime    : show how long the system has been up

#whodo    : 계정별(터미널별) 실행 프로세스

#who -b    : 부팅 일시

 

#swap -l   : swap 상태 보기

 

--------------------------------------------------------

* script로 보기

 

echo "The System-Hostname=`hostname`"
echo "The System-Uptime= `uptime|awk '{ print $3,$4,$5 }'`"
sm=`prtconf -pv|grep banner-name|awk -F"'" '{ print $2 }'`
echo "The system-make=$sm"
mm=`prtconf -pv|grep Mem|awk ' { print $3,$4 }'`
echo "The system-memory=$mm"
ps=`psrinfo|grep on-line|wc -l`
echo "The Sytem-process-count=,$ps"
mc=`ifconfig  -a|awk '/ether/ { print $2 }'`
echo "The System-MacAddress=$mc"
bt=`isainfo -kv`
echo "The System- kernel-type=$bt"

--------------------------------------------------------

 

  * HOST 이름
# uname -n    : whiteeye
# hostname    : whiteeye
# showrev     : Hostname: whiteeye
# sysdef      : whiteeye node name (NODE)


   * OS의 종류, 버젼
# uname -s    : SunOS
# uname -r    : 5.6
# uname -v    : Generic
# showrev     : Release:  5.6
# Kernel version:   SunOS 5.6 Generic August 1998
# sysdef      : 5.6 release (REL)
# SunOS system name (SYS)
# Generic version (VER)

   * 파티션 구성
# df -k       : Filesystem kbytes used avail capacity Mounted on
        /dev/dsk/c0t3d0s0 38383 19392 15161 56% /
        ...........

   * 패치 정보
# showrev -p  : Patch:  101331-03 Obsoletes:  Packages:  SUNWcsu.7
        11.5.0,REV=2.0.18,PATCH=35
        ........

   * 로드 되어 있는 모듈
# sysdef      : * Loadable Objects
        strmod/bufmod
        strmod/connld
       ......

   * 소프트웨어 패키지 구성
# pkginfo     : system      AXILvplr       Axil platform links
        system      AXILvplu       Axil usr/platform links
        ..............

 
2)   네트워크에 관한 정보는 다음과 같은 코맨드가 이용 가능하다.

   * IP Address, NetMask, Broadcast Address
# ifconfig -a : inet 129.158.153.162 netmask ffffff00 broadcast 120.158.153.255
 
 
 
3)   하드웨어의 구성 요소에 관한 상세한 정보는 다음과 같은 코맨드가 이용 가능하다.

   * 아키텍처 타입
# prtconf     : System Configuration: Sun Microsystems sun4m
# arch -k     : sun4m

   * Workstation 모델
# prtconf  : SUNW,SPARCstation-5
# prtconf -vp : ......
model: 'SUNW,501-2572'
clock-frequency: 0510ff40
name: 'SUNW,SPARCstation-5'
# dmesg       : root nexus = SUNW,SPARCstation-5

   * CPU 타입
# dmesg       : cpu0:  SUNW,UltraSPARC (upaid 0 impl 0x10 ver
0x22 clock 143 MHz)
# prtconf -vp :    ....
sparc-version: 00000008
mask_rev: 00000020
device_type: 'cpu'
name: 'FMI,MB86904'
# ok cpu-info : VPU FMI,MB86904 Rev. 2.0: 85Mhz
(EEPROM 코맨드)

   * 메모리 용량
# dmesg       : mem = 32768k (0x2000000)
# prtconf     : Memory size: 32 Megabytes
 
   * 시리얼 포트 디바이스
# dmesg       : zs0 at obio0: obio 0x1000000 sparc ipl 12
zs0 is /obio/zs@0,1000000
# sysdef      : zs, instance #0
zs, instance #1

   * 디스크
# dmesg       : sd3 at esp0: target 3 lun 0
sd3 is /iommu@0,10000000/sbus@0,10001000/espdma@5,8400000/
esp@5,8800000/sd@3,0
# sysdef      : sd, instance #2 (driver not attached)
sd, instance #3

   * 프레임 버퍼
# prtconf     : cgsix, instance #0
# prtconf -F  : /iommu@f,e0000000/sbus@f,e0001000/cgsix@2,0
# dmesg       : cgsix0 at sbus0: SNus slot 3 00 SBus level 5 sparc ipl 9
cgsix0 is /iommu@0,10000000/sbus@0,10001000/cgsix@3,0
cgsix0: screen 1152x900, single buffered, 1M mappable, rev 11
# sysdef      : cgsix, instance #0

 
 
4)   Root 디바이스와 Swap 디바이스 등의 정보는 /etc/vfstab 화일을 확인 하거나 다음의 코맨드의
   이용이 가능 하다.

   * Root 디바이스
# dmesg       : root on /iommu@0,10000000/sbus@0,10001000/espdma@5,8400000/
esp@5,8800000/sd@3,0:a fstype ufs

   * Swap 디바이스
# dmesg       : dump on /dev/dsk/c0t3d0s1 size 131532K
# swap -l     : swapfile dev swaplo blocks free
/dev/dsk/c0t3d0s1 32,25 8 263080 209312
# sysdef      : swapfile dev swaplo blocks free
/dev/dsk/c0t3d0s1 32,25 8 263080 209312

   * 시스템 보드 구성의 정보
# prtdiag(Sun4d, Sun4u 아키텍처만 가능)
PS. # /usr/platform/sun4u/sbin/prtdiag -v | more 플랫폼 정보를 한번에 확인
 
  * 로그 화일 : /var/sadm/system/logs/install_log
   OS의 인스톨 개시부터의 로그 정보가 화일에 기록 되어 있다. 이 화일에는 이하의
   내용이 있다.

    - 화일 시스템의 구성
    - 인스톨된 패키지의 종류
    - 인스톨된 소프트웨어의 총용량
    - 부트 디바이스

4) 로그 화일 : /var/sadm/system/logs/sysidtool.log
   OS를 인스톨할 때에 새로운 시스템에 관한 몇가지의 정보를 입력 한다. 이것은 sysidtool라고
   하는 일련의 프로그램에 따라 자동적으로 처리 된다. sysidtool의 로그 정보가 화일에 기록 된다.
    
    - Ethernet의 인터페이스 이름
    - 인스톨시에 설정한 IP 어드레스
    - 인스톨시에 설정한 Netmask의 값
    - 타임존
    - 선택한 네임 서비스의 종류

« PREV : 1 : 2 : 3 : 4 : 5 : 6 : 7 : ··· : 18 : NEXT »