grep 명령을 통해 특정 문자를 빼고 보기




리눅스 명령어중에 grep 명령으로 특정문자가 포함된 부분을 찾아내고는 합니다.


grep은 참 유용한 것인데, 가끔씩 이 글자 빼고 모두 보고 싶을 때가 있기도 하죠?

그럴때는

ex) cat 파일명 | grep -v "제외될 문자"

ex2) cat 파일명 | grep -ev "제외될 문자|제외될 문자|제외될 문자"

이와같이 -v  또는 -ev 옵션을 이용하여  제외될 문자를 설정하면 됩니다.


또다른 예로는 특정디렉토리의 파일 목록을 조회할 때도 사용가능 하지요.


ex1) ls -al | grep -v "제외될 문자"


디렉토리 목록중에서 특정문자가 들어간 파일 또는 폴더를 제외하고 출력이 되어집니다.


그럼 모드들 즐프하세요~

블로그 이미지

슬픈외로움

개발이 어려워? 모든것엔 답이있다...

,


ORA-12514: TNS:listener does not currently know of service requested in connect descriptor

ORA-12514: TNS 리스너가 현재 접속 기술자에 요청된 서비스를 알지 못함

오라클이 비정상적으로 종료되었을 경우 또는 다른 이유에 의해서 리스너가 SID 를 찾지 못하는 에러입니다.


해당 에러가 발생했을 경우 다음의 테스트를 우선 진행 합니다.



1. 리스너 점검


   - lsnrctl service  명령으로 현재 리스너 서비스가 정상인지 확인

   - lsnrctl status 명령으로 현재 리스너 서비스 상태 확인



2. 설정파일 점검


   - tnsnames.ora 파일과 listener.ora 파일의 설정을 다시 한번 확인


3. 오라클 및 리스너 재시작


   - 비정상 종료 또는 오라클 수행중 오류가 있다면, 오라클 shutdown 시에 에러메세지가 나올 수 있습니다.



설정상의 오류가 없다면, 위의 과정을 통해서 정상적으로 돌아갈 수 있을것입니다!!!



블로그 이미지

슬픈외로움

개발이 어려워? 모든것엔 답이있다...

,


database 백업 및 복원 방법


DB 백업하기

형식) mysqldump -u사용자이름 -p비밀번호 데이터베이스이름 > 파일이름

$ mysqldump -uroot -p12345 mydb > ./backup.sql
☞ SSH(보안텔넷)에서 사용자이름 root, 비밀번호 12345으로 접속하여 mydb의 내용을 backup.sql 파일에 저장함



DB 복원하기

형식) mysql -u사용자아이디 -p비밀번호 데이터베이스이름 < 파일이름

$ mysql -uroot -p12345 mydb < ./backup.sql
☞ backup.sql의 내용을 mydb에 복원함


블로그 이미지

슬픈외로움

개발이 어려워? 모든것엔 답이있다...

,

파일명이 깨진파일 지우기




리눅스 OS 에서 가끔 다운로드 받은 파일이나 , 특문등에 의해서 잘못생성되어진 파일들이 생길때가 있습니다.

이때 rm 명령으로 지우기가 난감하지요?


그럴땐 파일의 고유 ID 값을 이용하여 지울 수 있는 방법이 있습니다.


[root@test]# ls -li
합계 0
4532 -rw-r--r--. 1 root root 0 2015-09-23 03:57 2015.0922.txt
4531 -rw-r--r--. 1 root root 0 2015-09-23 03:53 ?ㄶ.txt



위처럼 ls 명령어의 -i옵션으로 파일의 고유 ID 값을 확인합니다. (맨앞 숫자)


[root@test]# find . -inum 4531 -exec rm -f {} ₩;


그다음 find 명령어를 통해 고유숫자 값을 입력하여 삭제합니다.


[root@test]# ls -li
합계 0
4532 -rw-r--r--. 1 root root 0 2015-09-23 03:57 2015.0922.txt



쨘~~ 파일명 깨진 파일 삭제된 것을 확인 할 수 있습니다.

블로그 이미지

슬픈외로움

개발이 어려워? 모든것엔 답이있다...

,

생성된 테이블의 CREATE TABLE 구문 얻기



mysql 에서 이미 생성되어져 있는 테이블(table) 에 대한 create table 구문을 얻어내는 방법입니다.



구문 : SHOW CREATE TABLE tbl_name



샘플)



mysql> SHOW CREATE TABLE t\G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE `t` ( `id` int(11) NOT NULL AUTO_INCREMENT, `s` char(60) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1





블로그 이미지

슬픈외로움

개발이 어려워? 모든것엔 답이있다...

,

ORA-00972: identifier is too long

ORA-00972: 식별자가 너무 깁니다



문제

Oracle 데이터베이스에서 이름이 30자보다 긴 열이나 테이블 같은 개체를 사용하려고 하면 다음 오류가 발생할 수 있습니다.

Oracle database error 972: ORA-00972: identifier is too long(Oracle 데이터베이스 오류 972: ORA-00972: 식별자가 너무 깁니다)

환경

  • Tableau Desktop
  • Oracle

해결 방법

Oracle 개체 이름이 30자 미만인지 확인하십시오.

원인

ORA-00972 오류는 Tableau Desktop이 아니라 Oracle 데이터베이스에서 발생합니다. 이 오류 메시지는 Oracle 데이터베이스 내의 개체가 30자를 초과한다는 것을 나타냅니다. 


블로그 이미지

슬픈외로움

개발이 어려워? 모든것엔 답이있다...

,

사용중인 리눅스 종류 및 버전 확인 방법


1 방법 1: /etc/*-release

명령어
grep . /etc/*-release
cat /etc/*-release | uniq
실행예시 (Ubuntu 14.04.3)
root@zetawiki:~# grep . /etc/*-release
/etc/lsb-release:DISTRIB_ID=Ubuntu
/etc/lsb-release:DISTRIB_RELEASE=14.04
/etc/lsb-release:DISTRIB_CODENAME=trusty
/etc/lsb-release:DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS"
/etc/os-release:NAME="Ubuntu"
/etc/os-release:VERSION="14.04.3 LTS, Trusty Tahr"
/etc/os-release:ID=ubuntu
/etc/os-release:ID_LIKE=debian
/etc/os-release:PRETTY_NAME="Ubuntu 14.04.3 LTS"
/etc/os-release:VERSION_ID="14.04"
/etc/os-release:HOME_URL="http://www.ubuntu.com/"
/etc/os-release:SUPPORT_URL="http://help.ubuntu.com/"
/etc/os-release:BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
실행예시 (CentOS 6.5)
[root@zetawiki ~]# grep . /etc/*-release
/etc/centos-release:CentOS release 6.5 (Final)
/etc/lsb-release:LSB_VERSION=base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch
/etc/redhat-release:CentOS release 6.5 (Final)
/etc/system-release:CentOS release 6.5 (Final)
실행예시 (Fedora 11 Leonidas)
[root@zetawiki ~]# cat /etc/*-release | uniq
Fedora release 11 (Leonidas)
실행예시 (Oracle Enterprise Linux Server 5.5)
[root@zetawiki ~]# cat /etc/*-release | uniq
Enterprise Linux Enterprise Linux Server release 5.5 (Carthage)
Red Hat Enterprise Linux Server release 5.5 (Tikanga)
실행예시 (SUSE Linux Enterprise Server 11)
zetawiki:~ # cat /etc/*-release | uniq
SUSE Linux Enterprise Server 11 (x86_64)
VERSION = 11
PATCHLEVEL = 1
LSB_VERSION="core-2.0-noarch:core-3.2-noarch:core-4.0-noarch:core-2.0-x86_64:core-3.2-x86_64:core-4.0-x86_64"




2 방법 2: /etc/issue*

명령어
grep . /etc/issue*
  • 배포판의 버전을 가장 쉽게 확인할 수 있는 방법이다.
  • 보안 등의 이유로 다른 내용으로 바뀌어 있는 경우도 있다.
실행예시 (Ubuntu 14.04.3)
root@zetawiki:~# grep . /etc/issue*
/etc/issue:Ubuntu 14.04.3 LTS \n \l
/etc/issue.net:Ubuntu 14.04.3 LTS
실행예시 (CentOS 6.5)
[root@zetawiki ~]# grep . /etc/issue*
/etc/issue:CentOS release 6.5 (Final)
/etc/issue:Kernel \r on an \m
/etc/issue.net:CentOS release 6.5 (Final)
/etc/issue.net:Kernel \r on an \m
실행예시 (Fedora 11)
[root@zetawiki ~]# cat /etc/issue
Fedora release 11 (Leonidas)
Kernel \r on an \m (\l)
실행예시 (Oracle Enterprise Linux 5.5)
[root@zetawiki ~]# cat /etc/issue
Enterprise Linux Enterprise Linux Server release 5.5 (Carthage)
Kernel \r on an \m
실행예시 (SUSE Linux Enterprise Server 11)
zetawiki:~ # cat /etc/issue

Welcome to SUSE Linux Enterprise Server 11 SP1  (x86_64) - Kernel \r (\l).

3 방법 3: rpm (레드햇계열)

rpm -qa *-release
실행예시 (CentOS 6.2)
[root@zetawiki ~]# rpm -qa *-release
centos-release-6-2.el6.centos.7.x86_64
실행예시 (Fedora 11 Leonidas)
[root@zetawiki ~]# rpm -qa *-release
fedora-release-11-1.noarch
실행예시 (Oracle Enterprise Linux Server 5.5)
[root@zetawiki ~]# rpm -qa *-release
enterprise-release-5-0.0.22
실행예시 (SUSE Linux Enterprise Server 11)
zetawiki:~ # rpm -qa *-release
sles-release-11.1-1.152
lsb-release-2.0-1.2.18



[제타위키내용 퍼왔습니다]

블로그 이미지

슬픈외로움

개발이 어려워? 모든것엔 답이있다...

,

MySQL에서 커버링 인덱스로 쿼리 성능을 높여보자!!


커버링 인덱스(Covering Index)라는 내용인데, 대용량 데이터 처리 시 적절하게 커버링 인덱스를 활용하여 쿼리를 작성하면 성능을 상당 부분 높일 수 있습니다.

커버링 인덱스란?

커버링 인덱스란 원하는 데이터를 인덱스에서만 추출할 수 있는 인덱스를 의미합니다. B-Tree 스캔만으로 원하는 데이터를 가져올 수 있으며, 칼럼을 읽기 위해 굳이 데이터 블록을 보지 않아도 됩니다.

인덱스는 행 전체 크기보다 훨씬 작으며, 인덱스 값에 따라 정렬이 되기 때문에 Sequential Read 접근할 수 있기 때문에, 커버링 인덱스를 사용하면 결과적으로 쿼리 성능을 비약적으로 올릴 수 있습니다.

백문이 불여일견! 아래 테스트를 보시죠.

테이블 생성

먼저 다음과 같이 테이블을 생성합니다.

create table usertest (
 userno int(11) not null auto_increment,
 userid varchar(20) not null default '',
 nickname varchar(20) not null default '',
 .. 중략 ..
 chgdate varchar(15) not null default '',
 primary key (userno),
 key chgdate (chgdate)
) engine=innodb;

약 1,000만 건 데이터를 무작위로 넣고 몇가지 테스트를 해봅니다.

커버링 인덱스(SELECT)

select chgdate , userno
from usertest
limit 100000, 100
************* 1. row *************
           id: 1
  select_type: SIMPLE
        table: usertest
         type: index
possible_keys: NULL
          key: CHGDATE
      key_len: 47
          ref: NULL
         rows: 9228802
        Extra: Using index
1 row in set (0.00 sec)

쿼리 실행 계획의 Extra 필드에 “Using Index” 결과를 볼 수 있는데, 이는 인덱스만으로 원하는 데이터 추출을 하였음을 알 수 있습니다.

이처럼 데이터 추출을 인덱스에서만 수행하는 것을 커버링 인덱스라고 합니다. 아시겠죠? ^^

그렇다면 일반 쿼리와 성능 테스트를 해볼까요?

커버링 인덱스(WHERE)

1) 일반 쿼리

select *
from usertest
where chgdate like '2010%'
limit 100000, 100

쿼리 수행 속도는 30.37초이며, 쿼리 실행 계획은 다음과 같습니다.

************* 1. row *************
           id: 1
  select_type: SIMPLE
        table: usertest
         type: range
possible_keys: CHGDATE
          key: CHGDATE
      key_len: 47
          ref: NULL
         rows: 4352950
        Extra: Using where

Extra 항목에서 “Using where” 내용은, Range 검색 이후 데이터는 직접 데이터 필드에 접근하여 추출한 것으로 보면 됩니다.

2) 커버링 인덱스 쿼리

select a.*
from (
      select userno
      from usertest
      where chgdate like '2012%'
      limit 100000, 100
) b join usertest a on b.userno = a.userno

쿼리 수행 시간은 0.16초이며 실행 계획은 다음과 같습니다.

************* 1. row *************
           id: 1
  select_type: PRIMARY
        table:
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 100
        Extra:
************* 2. row *************
           id: 1
  select_type: PRIMARY
        table: a
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: b.userno
         rows: 1
        Extra:
************* 3. row *************
           id: 2
  select_type: DERIVED
        table: usertest
         type: range
possible_keys: CHGDATE
          key: CHGDATE
      key_len: 47
          ref: NULL
         rows: 4352950
        Extra: Using where; Using index

Extra 에서 “Using Index”를 확인할 수 있습니다.

그렇다면 30초 넘게 수행되는 쿼리가 0.16초로 단축됐습니다. 왜 이렇게 큰 차이가 발생했을까요?

첫 번째 쿼리는 Where에서 부분 처리된 결과 셋을 Limit 구문에서 일정 범위를 추출하고, 추출된 값을 데이터 블록에 접근하여 원하는 필드를 가져오기 때문에 수행 속도가 느립니다.

두 번째 쿼리에서도 동일하게 Where에서 부분 처리된 결과 셋이 Limit 구문에서 일정 범위 추출되나, 정작 필요한 값은 테이블의 Primary Key인 userno 값입니다. InnoDB에서 모든 인덱스 Value에는 Primary Key를 값으로 가지기 때문에, 결과적으로 인덱스 접근만으로 원하는 데이터를 가져올 수 있게 됩니다. 최종적으로 조회할 데이터 추출을 위해서 데이터 블록에 접근하는 건 수는 서브 쿼리 안에 있는 결과 갯수, 즉 100건이기 때문에 첫 번째 쿼리 대비 월등하게 좋은 성능이 나온 것입니다.

커버링 인덱스(ORDER BY)

커버링 인덱스를 잘 사용하면 Full Scan 또한 방지할 수 있습니다. 대부분 RDBMS에는 테이블에 대한 통계 정보가 있고, 통계 정보를 활용해서 쿼리 실행을 최적화 합니다.

다음 재미있는 테스트 결과를 보여드리겠습니다. 전체 테이블에서 chgdate 역순으로 400000번째 데이터부터 10 건만 가져오는 쿼리입니다.

1) 일반 쿼리

select *
from usertest
order by chgdate
limit 400000, 100
************* 1. row *************
           id: 1
  select_type: SIMPLE
        table: usertest
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 9228802
        Extra: Using filesort
1 row in set (0.00 sec)

분명 인덱스가 있음에도, Full Scan 및 File Sorting이 발생합니다. 인덱스를 태웠을 때 인덱스 블록을 읽어들이면서 발생하는 비용보다 단순 Full Scan이 더 빠르다고 통계 정보로부터 판단했기 때문이죠. 인덱스도 데이터라는 것은 항상 기억하고 있어야 합니다^^

결과 시간은 책정 불가입니다. (안끝나요~!)

2) 커버링 인덱스 쿼리

위 결과와 다르게 커버링 인덱스는 조금 더 재미있는 결과를 보여줍니다.

select a.*
from (
      select userno
      from usertest
      order by chgdate
      limit 400000, 100
) b join usertest a on b.userno = a.userno
************* 1. row *************
           id: 1
  select_type: PRIMARY
        table:
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 100
        Extra:
************* 2. row *************
           id: 1
  select_type: PRIMARY
        table: a
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: b.userno
         rows: 1
        Extra:
************* 3. row *************
           id: 2
  select_type: DERIVED
        table: usertest
         type: index
possible_keys: NULL
          key: CHGDATE
      key_len: 47
          ref: NULL
         rows: 400100
        Extra: Using index

File Sorting이 발생하지 않고 커버링 인덱스가 사용되었으며, 실행 시간 또한 0.24초로 빠르게 나왔습니다.^^

Conclusion

커버링 인덱스는 InnoDB와 같이 인덱스와 데이터 모두 메모리에 올라와 있는 경우에 유용하게 쓰일 수 있습니다. 물론 커버링 인덱스가 좋기는 하지만, 커버링 인덱스를 사용하기 위해 사용하지 않는 인덱스를 주구장창 만드는 것은 최대한 피해야 하겠죠^^

잊지마세요. 인덱스도 데이터라는 사실을..

블로그 이미지

슬픈외로움

개발이 어려워? 모든것엔 답이있다...

,


데이터베이스 테이블 깨짐 현상 체크 및 복구



MySQL 에서는 테이블이 손상 되었는지 여부를 확인(check table)하고, 손상된 테이블이라면 테이블을 복구(repair table)하고, 속도 개선을 위해 테이블을 최적화(optimize table) 하는 기능들을 제공한다. 이 기능들에 대한 쿼리는 상당히 단순하다.



1. MySQL 특정 테이블 체크(check)

DB 콘솔 접속 후

# use [DB명];                   => 작업할 DB를 선택

# check table [테이블명];   => 확인할 테이블을 체크



2. MySQL 특정 테이블 복구(repair)

DB 콘솔 접속 후

# use [DB명];                   => 작업할 DB를 선택                 

# repair table [테이블명];    => 복구할 테이블을 복구



3. MySQL 특정 테이블 최적화(optimize)

DB 콘솔 접속 후

# use [DB명];                    => 작업할 DB를 선택

# optimize table [테이블명]; => 최적화할 테이블을 최적화



그리고 위와 같이 특정 테이블에 대해 체크, 복구, 최적화를 할 수 있으나, 서버 장애 등으로 인해 DB의 전체 상태를 점검하거나 전체를 최적화하고 싶을 때는 테이블 하나하나 확인을 하기 어렵다. 그럴 때 아래와 같이 특정 DB의 모든 테이블을 체크하고, 복구하고, 최적화 할 수 있다.



4. MySQL 특정 DB의 모든 테이블 체크 및 자동 복구

서버 콘솔에서

# cd [MySQL_HOME]/bin                                                                

=> MySQL 설치 홈의 bin 폴더로 이동

# ./mysqlcheck -u [DB계정] -p[패스워드] --auto-repair [DB명]           

=> 해당 DB의 모든 테이블을 체크 및 자동복구



5. MySQL 특정 DB의 모든 테이블 최적화

서버 콘솔에서

# cd [MySQL_HOME]/bin                                                                

=> MySQL 설치 홈의 bin 폴더로 이동

# ./mysqlcheck -u [DB계정] -p[패스워드] --optimize [DB명]               

=> 해당 DB의 모든 테이블을 최적화


블로그 이미지

슬픈외로움

개발이 어려워? 모든것엔 답이있다...

,


쿼리에서 대소문자 비교하기



일반적으로 MySQL Where 조건에서 비교를 하면 대소문자 구분없이 값을 찾습니다.


이때 binary 펑션으로 감싸주면 대소문자 비교가 가능합니다~





member_table

idx

id

1

SangMin

2

sangmin

3

minsu

4

minyoung


이런테이블이있다고할때


select id from member_table where id = 'sangmin'

이렇게 쿼리를 하면 id 가 SangMin, sangmin 두개의 데이터를 가져오는데용


이런 경우에는 위의 쿼리문을 아래와 같이 변경하여 보면..

select id from member_table where binary(id) = 'sangmin'


binary 함수를 이용하면 대소문자를 구별해서 데이터를 가져옵니다

대소문자 구별이 필요한 곳에는 반드시 이용이 필요할 것입니다요~~


블로그 이미지

슬픈외로움

개발이 어려워? 모든것엔 답이있다...

,