프로그래밍/Ruby on rails 2014. 1. 8. 19:38

RVM이란?

루비 좀 안다고 하는 사람들에게 루비를 어떻게 설치하냐고 물어보면 RVM으로 설치하라는 이야기를 많이 들을 수 있습니다. RVM은 Ruby Version Manager의 약자로, 여러 버전의 루비를 쉽게 관리할 수 있게 해주는 스크립트입니다. 

한 시스템에 여러 버전의 루비를 설치하기는 쉽지 않습니다. 일반적인 리눅스의 패키지 시스템으로 동시에 여러 버전의 루비를 깔면 환경변수 꼬이고 gem 꼬이고 난리도 아니죠. 그렇기 때문에 시스템에 이미 작업하고 있는 프로젝트가 있을 때 새로 릴리즈된 루비 버전을 사용해보기는 쉽지 않습니다. 이미 구버전 루비에서 작업한 기존 프로젝트가 어떻게 될지 모르기 때문이죠. 하지만 rvm을 사용하면 여러 버전의 루비, 심지어 gem도 따로 관리해주기 때문에 새 버전을 써보고 다시 전환하기가 쉽습니다. 여기에 더해 gemset 기능을 사용하면 프로젝트별로 별도의 루비 버전을 사용하는 일도 가능합니다.

rvm의 설치 자체는 홈페이지에 있는 스크립트를 그대로 실행하면 되는 아주 간단한 작업입니다. 다만 몇 가지 주의해야 할 사항들이 있는데 이런 것들을 모른 채 설치하면 메뉴얼대로 작동하지 않고, “분명 시키는 대로 했는데 왜 안돼!” 하고 rvm은 물론 루비는 매우 설정이 거지같은 언어라는 안타까운 편견에 빠지게 됩니다.저도 처음엔 고생 꽤나 했구요…

서버 세팅하다 꼬이거나 CSS를 짜다 보면 이런 기분이 듭니다.

이 포스트는 ubuntu 12.04 64bit 기준으로 작성되었습니다.

RVM 설치하기…전에 하면 안되는 일들!

인스톨 방법을 쓰기 전에, 먼저 잘못된 설치법부터 설명하겠습니다.

이 포스트에서 제일 중요한 내용입니다.
절대, 네버, 무슨 일이 있어도 이렇게 깔지 마세요!

apt-get으로 까는 사람들이 많을 수 밖에 없는 이유

우분투가 rvm이 없으면 이렇게 깔라고 친절하게 인도해줘서 속는 사람들이 너무 많습니다. ㅠㅠ

우분투의 apt는 대부분의 패키지들을 apt-get install 명령어 하나로 한방에 깔 수 있게 해주는 멋진 도구입니다. 그런데 이 rvm을 apt-get으로 깔면 무슨 일이 생기냐구요?

설치 테스트와 트롤링을 위해 준비된 VM들

숙련된 VM의 시범을 한번 보겠습니다.

이 포스트를 작성하는 현재 RVM의 최신 버전은 1.24.7입니다…

낡아도 이렇게 낡을 수가 없습니다…

‘구버전이라도 기능만 잘 돌아가면 되겠지?’ 하고 루비를 깔아보겠습니다.

원래 ruby-1.9.3-pxxx등으로 patch level이 쓰여져야 하는데 1.9.3-에서 끝나네요

잘못된 경로로 찾아가서 루비를 제대로 깔 수도 없습니다.
2.0같은건 아예 리스트에 존재하지도 않아요… ㅠㅠ

‘구버전이니까 업데이트를 하면 되겠지? 업데이트를 해보자!’

 

그냥 포기하고 멀쩡한 버전을 깔아봅니다.

클릭하시면 스택오버플로우 링크로 이동합니다

심지어 멀쩡한 버전을 깔려는데도 얘가 방해를 하고 있어서 치워줘야 합니다.
혹시 apt-get으로 rvm을 까셨다면 싹싹 지워줍니다.

1. 패키지를 apt-get –purge로 날려주고, /usr/share, /etc/ 에 있는 스크립트들을 지워줍니다.

싹싹 지워서, 시스템에 후환(?)이 없도록 합시다.

2. 삭제 후에는 shell을 재실행해 이미 로드된 환경변수들이 다시 사라지도록 해줍니다.

하루빨리 우분투에서 이 거지같은 패키지가 사라졌으면 하는 바람입니다.

RVM 진짜로 설치하기

RVM의 설치에는 두 가지가 있습니다. 잘 읽고 원하는 방법을 골라 설치하세요.

Single User Install

  • 설치한 유저에게만 RVM이 깔립니다.
  • 설치한 RVM은 당연히 ‘그 유저’만 쓸 수 있고, 다른 유저가 사용할 수 없습니다.
  • RVM은 설치한 유저의 홈 디렉토리의 .rvm폴더 ($HOME/.rvm)에 설치되고,
    RVM으로 설치하는 ruby와 모든 gem들도 $HOME/.rvm에 저장됩니다.
  • 여러 유저가 각각 Single User Install을 하면 모든 ruby와 gem들은 별도로 저장됩니다.
    시스템 공용으로 사용하는 것은 rvm install에서 루비를 설치하기 위해 설치한 라이브러리뿐입니다.
  • root계정으로 Single User Install을 할 수 없습니다.
    root permission을 가진 상태면 자동으로 multi user 인스톨을 하므로,
    root계정에만 rvm을 깔아서 쓰는 것은 불가능하진…않은데 이 포스트에서는 다루지 않습니다.
    root 계정에만 rvm Single user Install로 설치하기

Multi User Install

  • /usr/local/rvm/ 에 모든 rvm, ruby, gem이 설치됩니다.
  • 한 유저가 설치한 루비, 또는 gem은 시스템 전체에 공유됩니다.
  • 시스템의 모든 유저가 rvm, rvm으로 설치한 루비와 gem을 사용 가능합니다.
  • rvm그룹의 유저만 새 루비 또는 gem을 설치할 수 있습니다.

자 고르셨나요? 그럼 따라해 봅시다.

Single User Install 방법

1. root가 아닌 일반 유저로 아래 명령을 실행합니다. (\ 오타 아닙니다!!)

2. 쉘을 껐다 켜거나 rvm스크립트를 현재 쉘에 로드해줍니다.

끝! 쉽죠?

Multi User Install 방법

1. root가 아닌 일반 유저로 아래 명령을 실행합니다. (\ 오타 아닙니다!!)

bash 앞에 sudo만 붙여주면 됩니다. 와!

실제로 root로 설치해 봤을때 특별히 이상한 점은 찾지 못했는데,
rvm 문서를 보면 root와 일반 유저의 환경변수 차이 때문에
root로 직접 깔지 말고 일반 유저에서 sudo를 써서 사용하라고 합니다.
시키는 대로 하는게 편하겠죠?

2. 그 다음 RVM을 사용할 유저들을 rvm 그룹에 추가합니다.

그룹에 추가를 안해주면 /usr/local/rvm에 write권한이 없어서 루비 설치가 불가능합니다

일반 유저는 /usr/local/rvm에 write권한이 없기 때문에 rvm 그룹에 추가해서 권한을 부여해야 합니다.
이게 없으면 rvm install등을 할 때 권한이 없다고 죽어버려요.

3. 쉘을 껐다 켜거나
(쉘을 껐다 켤 수 없는 상황이면) 그룹 권한을 재로드하고, rvm스크립트를 현재 쉘에 로드해줍니다.

이번에는 그룹 권한도 다시 로드 해야해서 좀 귀찮습니다.
그래서 쉘을 그냥 껐다 켜는게 편해요.

축하합니다! RVM 설치가 끝났습니다!

RVM으로 Ruby 설치하기

sudo같은거 붙일 필요도 없고 붙여서도 안됩니다.
이 과정에서 permission denied가 뜨면 대부분 그룹 문제이기 때문에
id를 쳐서 유저가 rvm 그룹인지 확인해보세요.

이미지가 너무 길어서 잘 안보이는데 끝에 보면 1001(rvm) 이렇게 써있습니다 ㅠㅠ
그룹에 추가했는데도 없으면 쉘을 재실행하거나 위에서 알려준 커맨드로 그룹 권한을 재로드해보세요.

설치 도중 sudo권한이 필요하면 알아서 물어봅니다.

설치 중 시스템 업데이트가 필요해 sudo권한이 필요한 경우가 있는데, 이 경우엔 알아서 물어봅니다.
rvm커맨드에 따로 먼저 sudo를 붙여야 하는 경우는 전혀 없으니,
혹시 permission denied가 뜨면 그룹을 먼저 확인해주세요.

네, 이제 루비 코딩을 시작하시면 됩니다!

TroubleShooting

Q: 루비 스크립트에서 sudo권한이 필요한데, sudo를 쓰면 rvm을 찾을 수 없다고 나오네요. 어쩌죠?

Single User Install에서 볼 수 있는 현상인데, rvm은 우리의 로그인 쉘에 로드되는 스크립트이기 때문에 root에는 깔려있지 않고 깔려 있다 하더라도 그 스크립트를 로드하지 않습니다 ㅠㅠ

sudo 대신 rvmsudo를 사용하면 현재 쉘의 루비를 가지고 sudo권한으로 실행할 수 있습니다.

Q: sudo -s,  su [username]등으로 유저를 바꾸고 그 유저의 rvm을 쓸 수 없나요?

sudo -s, su [username]은 로그인 쉘이 아니라 스크립트를 로드하지 않습니다.
su – [username] 으로 하면 그 유저의 로그인 쉘을 띄우기 때문에 그 유저의 rvm을 쓸 수 있습니다.

Q: 이미 시스템 루비가 있는데 지워야 하나요?

rvm 경로가 $PATH의 가장 앞에 붙기 때문에 시스템 루비는 남아있어도 상관없습니다.

출처 : http://bigmatch.i-um.net/ 이음소시어스 개발팀 블로그


//
데이터베이스 2013. 11. 4. 02:53

Oracle 11g XE가 설치된 경로(디폴트, c:\oraclexe)에서 검색하여 scott.sql 파일을 찾고 그 경로를 복사한다.

시작 > Oracle 11g XE > Run SQL CommandLine > 커맨드 창에 위에서 복사한 내용을 이용하여 다음과 같이 입력한다.

 


SQL> conn /as sysdba

SQL> @C:\oraclexe\app\oracle\product\11.2.0\server\rdbms\admin\scott.sql<enter>

SQL> alter user scott identified by tiger;<enter>

SQL> conn scott/tiger;<enter>

SQL> select * from emp;<enter>


'데이터베이스' 카테고리의 다른 글

MySQL 비밀번호 복구  (0) 2014.05.31
mysql 패스워드 분실시에  (0) 2014.04.04
DB index 사용하기  (0) 2013.10.15
mysql 기본사용  (0) 2013.01.20
mysql 사용자 권한 넣기  (0) 2013.01.02
//
데이터베이스 2013. 10. 15. 14:39


데브피아에서 기가 막히게 좋은 전문가 글을 찾았습니다. 간단하게 정리해 봅니다.

인덱스를 사용하기를 기대하지만 그렇지 않은 기본적이고 대표적인 예입니다.

1. 인덱스 컬럼을 변형하여 비교할 때

BAD
WHERE TO_CHAR(HIREDATE,'YYYYMMDD') = '19980518';
GOOD
WHERE HIREDATE = TO_DATE('19980518')


BAD
WHERE SALARY + 1000 > 100000;
GOOD
WHERE SALARY > 100000 - 1000;


비교하는 인덱스 컬럼의 형이나 값을 변경하면 발생합니다.
이 경우에는 비교값을 변경해 주어야 인덱스를 사용하게 됩니다.

2. 비교 대상의 형이 달라서 내부적으로 형변환을 하는 경우

BAD
WHERE EMP_ID = 200383;
GOOD
WHERE EMP_ID = ‘200383’;


EMP_ID가varchar라고 할 경우에 비교값이 숫자인 경우에 DB에서 자동으로 이를 숫자로 변경하고 비교하게 됩니다. 이 경우에 인덱스 컬럼에 변형이 일어났기 때문에 인덱스를 사용하지 못하게 됩니다.

3. NULL을 비교하는 경우

BAD
WHERE JOB IS NULL;


일반적으로 Oracle을 기준으로 NULL은 인덱스 대상이 아니라고 합니다. 따라서, 이를 해결하기 위해서는 NULL을 쓰지 말고 다른 정해진 값을 이용해서 비교해야 합니다. (흠..이건 좀...)

4. 부정형 조건인 경우

BAD
WHERE JOB NOT IN ( 'INSTRUCTOR','STAFF'); 


부정형 역시 인덱스를 사용하지 못하는 대표적인 조건 쿼리 입니다. 아닌 놈을 찾으려면 전체를 뒤지는 수 밖에요. 이를 피하기 위한 근본적인 DB 모델링이 중요합니다.


이하 원문을 그대로 가져다 붙입니다. 추가 설명이 필요하면 읽어 보세요.
http://www.devpia.com/DevStudy/Lecture/OffLineDetail.aspx?nSemiID=1429&lectype=evt

필자가 처음에 SQL을 배울 때 SQL이 상당히 이상했다. 원하는 것만 요구할 뿐 어떻게 가져오라는 정보가 SQL에는 없었기 때문이다. FILE레벨의 I/O까지 코딩에 익숙한 필자에게 절차가 없다는 것이 오희려 더 이상했던 것이다.
물론 상세한 과정이 필요하지 않으므로 편리하고 좋았다 그러나 어떻게 가져오는지는 알지못하고 단지 사용할 뿐이었다.
그러나 SQL이 PLAN이라는 실행 계획을 만들고 그에 따라 가져오게 된다는 사실은 안것은 한참 뒤에 일이었다.
저자소개: 유원석
(現) (주)위즈베이스 컨설팅본부 수석컨설턴트
프로젝트 :
ㆍ하나투어 DB아키텍터
ㆍSK Telecom NGM Project 시스템 성능관리자
ㆍKT EDW Projec Main Architect 수행
ㆍLG 전자 Eagle Project 시스템 성능 개선 등
강 의 :
ㆍ한국썬마이크로시스템즈 대용량데이터베이스
ㆍ한국썬마이크로시스템즈 Orange를 이용한 DB튜닝
결국은 내가 하지않은 일을 Optimizer라는 프로그램이 대신 해주고 있는 것이 아닌가? 그래서 정말 고마운 놈이라고 생각했었다. 그러나 밑는 도끼에 발등을 찍힌다는 말이 있지 않은가?
Plan에 index를 달아주어도 Index를 사용하지 않고 full table scan만 하고 있으니 당체 속도가 나지를 않았다.
이래저래 해서 나중에 알게되었지만 결국 컬럼의 변형을 가하면 index를 사용하지 못한다는 것이다. 우리가 직접 사용하지는 않지만 결국 우리가 SQL을 사용한다는 것은 Optimizer라는 놈에게 SQL의 수행을 부탁하는 것이다. 따라서 우리가 Optimizer에 대해서 잘 안다면 SQL을 좀더 효율적으로 수행하도록 할 수 있지 않은가!
그러면 인덱스를 달았을 때 Optimizer가 index를 사용하지 못하는 경우를 통해서 우리가 애써(?)생성한 인덱시가 무용지물이 되지 않도록 해보자.
아래예제에 사용할 TABLE LAYOUT이다.
EMPLOYEES
---------
Rows=15,132
Empty Blocks=7
Chain Count=0
Avg Space Freelist Blocks=0
Sample Size=15,132
Partitioned=NO

Blocks=121
Avg Space=885
Avg Row Length=51
Freelist Blocks=0
Last Analyze=2009/05/04
Column Name
---------------
EMP_ID
MGR_ID
LAST_NAME
FIRST_NAME
HIREDATE
JOB
SALARY

Nullable
-----------------


NOT NULL
Column Type
-----------------
VARCHAR2(40)
VARCHAR2(40)
VARCHAR2(24)
VARCHAR2(14)
DATE
VARCHAR2(24)
NUMBER(7,2)
Distinct
-----------------
15,132 
679 
9,443 
3,579 
3,903 
53 
3,267
Buckets
------------------
75
75
75
75
75
53
75
INDEX
--------------------------------------------------------------------------------------
IDX_GENDER : GENDER
      Type=NORMAL, Uniq=No, Distinct=2, Rows=15,132, Last Analyze=2009/05/04
IDX_HIREDAT : HIREDATE
      Type=NORMAL, Uniq=No, Distinct=3,903, Rows=15,132, Last Analyze=2009/05/04
IDX_JOB : JOB
      Type=NORMAL, Uniq=No, Distinct=53, Rows=15,129, Last Analyze=2009/05/04
IDX_SALARY : SALARY
      Type=NORMAL, Uniq=No, Distinct=3,267, Rows=15,132, Last Analyze=2009/05/04
IDX_TYPE2 : TYPE
      Type=NORMAL, Uniq=No, Distinct=6, Rows=15,132, Last Analyze=2009/05/04
PK_EMP_ID : EMP_ID
      Type=NORMAL, Uniq=No, Distinct=15,132, Rows=15,132, Last Analyze=2009/05/04
필자가 여러군데 튜닝을 하면서 가장 많이 본것중에 하나는 INDEX를 달았으나 쓰지 못하게 되는 경우이다. 대표적인 경우가 아래와 같이 날짜타입(HIREDATE)에 TO_CHAR를 씌운 경우이다.
SELECT FIRST_NAME, LAST_NAME
FROM EMPLOYEES
WHERE TO_CHAR(HIREDATE,'YYYYMMDD') = '19980518';
물론 INDEX는 아래와 같이 생성되어있다.
CREATE INDEX IDX_HIREDATE ON EMPLOYEES(HIREDATE);
우리가 원하는 것은 INDEX를 타고 테이블을 가져오기를 바란것이었다.

그러나 실제 PLAN은 아래와 같이 나온다.
Execution Plan
--------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=28 Card=151 Bytes=3K)
1 0 TABLE ACCESS (FULL) OF 'EMPLOYEES' (TABLE) (Cost=28 Card=151 Bytes=3K)
TABLE ACCESS (FULL) 이란 뜻은 INDEX를 타지 않고 테이블을 처음부터 끝까지 읽어서 찾는다는 뜻이다. 한마디로 10건이며 10건읽고 100만건이면 100만건을 다 읽어야 결과가 나온다는 말이다.

OPEN시에는 빠르던 시스템이 시간이 지날수록 느려지는 결정적인 역할을 하는 것이 바로 위와 같은 경우이다. 그럼 어떻게 해야 제대로 인덱스를 사용할 수 있을가?
일단 간단히 SQL의 수정으로 해결할수 있다. HIREDATE는 날짜 타입이다.
따라서 인덱스를 HIREDATE로 했을 때 인덱스를 타기위해서는 INDEX를 생성한것에 변형을 주어서는 안된다.
SELECT FIRST_NAME, LAST_NAME
FROM EMPLOYEES
WHERE HIREDATE = TO_DATE('19980518')
따라서 간단하게 위와 같이 고치면 INDEX를 사용하게된다.
Execution Plan
--------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=3 Card=4 Bytes=92)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMPLOYEES' (TABLE) (Cost=3 Card=4 Bytes=92)
2 1 INDEX (RANGE SCAN) OF 'IDX_HIREDATE' (INDEX) (Cost=1 Card=4)
물론 결과도 빠르게 나온다 그러나 중요한 점이 있다 결과가 같을까?
운이 좋으면 결과가 같을 것이고 대부분의 경우는 결과가 틀리다.
왜 그럴까?
날짜 타입은 날짜와 시분초의 정보도 가지고 있다. 따라서 TO_DATE(‘19980518’)라는 말은 정확히 1998년5월18일 0시0분0초라는 뜻이다. 그래서 우리가 원하는 1998년5월18일자와는 차이가 있다.
따라서 1998년5월18일 0시0분1초 ~ 23시59분59초까지의 데이터는 나오지 않게되는것이다.
이것은 튜닝할 때 유의할 점이다. 결과를 같게 유지해야하는것이다. 이 상황을 알고있다면 방법은 간단하다.
아래아 같이 고치면 빠른시간에 원하는 결과를 얻을 수 있을 것이다.
SELECT FIRST_NAME, LAST_NAME
FROM EMPLOYEES
WHERE HIREDATE BETWEEN TO_DATE('19980518'||'00:00:00','YYYYMMDD HH24:MI:SS')
AND TO_DATE('19980518'||'23:59:59','YYYYMMDD HH24:MI:SS')
비슷하지만 함수의한 변형이 아닌 간단한 연산에의한 변형의 경우도 마찬가지이다.
$1000의 인센티브를 더주면 $10000이 넘는 사람을 찾는 SQL을 만들어보자.
아마 아래와 같을 것이다.
SELECT FIRST_NAME, LAST_NAME
FROM EMPLOYEES
WHERE SALARY + 1000 > 100000;
물론 INDEX는 아래와 같이 만들었다.
CREATE INDEX IDX_SALARY ON EMPLOYEES(SALARY);
그러나 PLAN을 보자
Execution Plan
--------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=29 Card=757 Bytes=13K)
1 0 TABLE ACCESS (FULL) OF 'EMPLOYEES' (TABLE) (Cost=29 Card=757 Bytes=13K)
인데스를 타지 못한다. 왜일까. 간단한 연산이지만 SALARY컬럼에 가공을 했기 때문에 OPTIMIZER는 인덱스를 타는 것을 포기해버린다.
따라서 우리가 기초적인 수학 실력을 발휘해서 이항을 해준다면 아래와 같은 조건이 될것이다.
SELECT FIRST_NAME, LAST_NAME
FROM EMPLOYEES
WHERE SALARY > 100000 - 1000;
이경우에 PLAN을 보자.
Execution Plan
--------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=3 Card=1 Bytes=17)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMPLOYEES' (TABLE) (Cost=3 Card=1 Bytes=17)
2 1 INDEX (RANGE SCAN) OF 'IDX_SALARY' (INDEX) (Cost=2 Card=1)
재미 있게도 이번에 제대로 된 인덱스를 탄다. Optimizer가 바보 같다는 생각이 들지 않는가?
물론 바보같다. 그러나 OPTIMIZER나름대로 깊은 고민이 있다. 아주 잛은 시간내에 OPTIMIZER는 많은 경우의 수를 타진해야한다. 따라서 이항연산과 같은 것 까지 검토하면 너무 많은 시간을 소모하게 된다 따라서 그런부분은 포기한것이다.

또다른 경우중에 하나가 DB의 내부적인 변형이다. 이는 개발자가 의도하지 않게 문제를 야기하는 경우이다.
여기 PK 조건으로 검색하는 SQL이 있다.
SELECT LAST_NAME,FIRST_NAME
FROM EMPLOYEES
WHERE EMP_ID = 200383;
그러나 PLAN은 아래와 같이 나왔다.
Execution Plan
--------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=29 Card=1 Bytes=19)
1 0 TABLE ACCESS (FULL) OF 'EMPLOYEES' (TABLE) (Cost=29 Card=1 Bytes=19)
분명히 아래와 같은 INDEX를 생성하였다.
CREATE INDEX PK_EMP_ID ON EMPLOYEES(EMP_ID);
왜 인덱스를 안타는 것일까?
그 이유은 OPTIMIZER의 내부 변형 규칙에 있다.
일반적으로 비교를 하려면 두개의 데이터 형이 같아야 한다.
그런데 EMP_ID는 VARCHAR2(40)이다 그리고 비교하려는 것은 200383이라는 숫자이다.
따라서 숫자와 문자는 비교할수 없기 때문에 내부적으로 변형이 이루어진다.
문자보다 숫자가 우선순위가 높아서 문자와 숫자를 비교하게되면 문자쪽이 숫자로 변형되어 비교하게 되는 것이다.
따라서 위의 SQL은 OPTIMIZER는 아래와 같은 SQL로 수행하게된다.
EMP_ID를 TO_NUMBER(EMP_ID) = 2000393과 같이 처리하게 된다.
SELECT LAST_NAME,FIRST_NAME
FROM EMPLOYEES
WHERE TO_NUMBER(EMP_ID) = 200383;
이는 처음 예제에서 날짜 컬럼에 TO_CHAR를 씌원것과 같은 효과이다. 따라서 이문제를 해결하기위해서는 반대쪽, 즉 2000293을 문자로 변환해주면 문자대 문자의 비교이므로 내부적 변형이 발생하지 않게된다.
SELECT LAST_NAME,FIRST_NAME
FROM EMPLOYEES
WHERE EMP_ID = ‘200383’;
 
Execution Plan
--------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=2 Card=1 Bytes=19)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMPLOYEES' (TABLE) (Cost=2 Card=1 Bytes=19)
2 1 INDEX (RANGE SCAN) OF 'PK_EMP_ID' (INDEX) (Cost=1 Card=1)
아래 SQL을 보자 JOB에 NULL인 조건을 검색하는 것이다.
SELECT LAST_NAME,FIRST_NAME
FROM EMPLOYEES
WHERE JOB IS NULL
아래 SQL을 보자 JOB이 NULL인 조건을 검색하는 것이다.
물론 아래와 같은 JOB INDEX를 생성하였다.
CREATE INDEX IDX_JOB ON EMPLOYEES (JOB);
아래 PLAN을 보자 왜 IDX_JOB INDEX를 타지 못하는가?
Execution Plan
--------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=29 Card=3 Bytes=63)
1 0 TABLE ACCESS (FULL) OF 'EMPLOYEES' (TABLE) (Cost=29 Card=3 Bytes=63)
이경우에는 Oracle의 경우 일반적으로 index를 생성할 때 null값은 index항목에 넣지 않는다. 따라서 null은 index에 없기 때문에 null조건을 준다면 그것은 index를 탈수 없다.
따라서 위와 같은 경우 반드시 index를 타려거든 job컬럼을 NOT NULL로 설정하고 NUL대신 특정값 (예를 들면 : ‘NOT ASSIGN’ ) 으로 설정하고 QUERY를 아래와 같이 수정한다면 인덱스를 탈수 있을 것이다.
SELECT LAST_NAME,FIRST_NAME
FROM EMPLOYEES
WHERE JOB = ‘NOT ASSIGN’;
아래 SQL를 하나 더 보자
SELECT LAST_NAME,FIRST_NAME
FROM EMPLOYEES
WHERE JOB NOT IN ( 'INSTRUCTOR','STAFF');
이번의 NULL을 비교한것도 아닌데 INDEX를 사용하지 못한다. 이것은 일반적인 INDEX가 =이나 <, > , BETWEEN조건에 만 인덱스를 탈수 있고 부정형으로 비교했을때는 인덱스를 탈수 없기때문이다.
생각해보자 어떤 것을 순서대로 정리해 놓았는데 그것이 아닌 것을 찾으려고 한다면 전체를 다 읽어봐야지만 아니것을 알수 있지 않은가?
따라서 가급적 프로그램 구성에서 부정형 조건이 들어가게 한다는 것은 성능을 저하시킬 가능성이 매우 높기 때문에 이런 조건이 되지 않도록 설계단설계부터 고려해야한다.

이상은 간단하게 INDEX를 주었을 때 일반적으로 INDEX를 타지 못하는 경우를 든것이다. 사실 위예 예처럼 실제 프로젝트에서 많은 부분이 INDEX를 생성하고도 OPTIMIZER의 특성을 몰라서 INDEX를 쓰지 못한채 APPLICATION이 돌고 있다. 이는 곧바로 자원의 과도 사용으로 나타나고 느린 응답시간으로 나타나게 된다. 항상 시스템을 OPEN하고 마음을 조리지 않으려면 내가 생성된 INDEX를 잘 탈수 있게 내가 SQL을 잘 작성했는지 검토해 보기 바란다.
아래 4개의 항목은 반드시 기억해 두기 바란다.
인덱스를 사용하지 못하는 경우는 아래와 같다.
  • 인덱스 컬럼에 변형이 일어난 경우
    • WHERE TO_CHAR(HIREDATE,'YYYYMMDD') = '19980518';
    • WHERE SALARY + 1000 > 100000;
  • 내부적인 변형이 일어난 경우
    • WHERE EMP_ID = 200383;
  • NULL을 비교하였을 경우
    • WHERE JOB IS NULL;
  • 부정형으로 조건을 기술한 경우
    • WHERE JOB NOT IN ( 'INSTRUCTOR','STAFF');

물론 이 경우 이외에 Optimizer의 판단에 따라서 인덱스를 사용하지 못하는 경우도 있다. 그러나 대부분의 경우에는 위에 항목을 만족한다면 원하는 index를 타는 효율적인 sql작성에 좋은 기준이 될것이다. 마지막으로 sql을 작성한후 반드시 plan을 확인해 보기 바란다.
실제 plan이 어떻게 되는냐를 확인해보지 않으면 무심코 과거의 실수를 답습할 수 있기때문이다.


'데이터베이스' 카테고리의 다른 글

mysql 패스워드 분실시에  (0) 2014.04.04
오라클 scott 유저 활성화  (0) 2013.11.04
mysql 기본사용  (0) 2013.01.20
mysql 사용자 권한 넣기  (0) 2013.01.02
mysql 컬럼 수정 삭제 추가  (0) 2012.12.09
//
컴퓨터사용중 2013. 10. 14. 15:38

대분류

단축키

  

  

  

  

소분류

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

파일

         

  

  

CTRL+

 

N

  

새로 만들기

  

  

  

CTRL+

 

O

  

열기

   

  

  

CTRL+

 

F4

  

닫기

   

  

  

CTRL+

 

S

  

저장

   

  

  

  

F12

  

다른 이름으로 저장

 

  

  

CTRL+

 

P

  

인쇄

   

  

  

CTRL+

 

F2

  

인쇄 미리보기

  

  

  

 

ALT+

F4

  

끝내기

   

  

편집

         

  

  

CTRL+

 

Z

  

작업 취소(undo)


 

  

  

CTRL+

 

Y

  

작업 반복(redo)

  

  

  

 

SHIFT +

화살표

  

블록 설정

  

  

  

 

SHIFT +

Home

  

줄의 처음까지 블록 설정

 

  

  

 

SHIFT +

End

  

줄의 끝까지 블록 설정

 

  

  

CTRL+

 

X

  

잘라내기

  

  

  

CTRL+

 

C

  

복사

   

  

  

CTRL+

 

V

  

붙여넣기

  

  

  

  

Del

  

지우기

   

  

  

CTRL+

 

A

  

모두 선택

  

  

  

CTRL+

 

F

  

찾기

   

  

  

CTRL+

 

H

  

바꾸기

   

  

  

  

F5

  

이동

   

  

  

CTRL+

 

Page Down

 

다음 페이지로 이동

 

  

  

CTRL+

 

Page Up

 

이전 페이지로 이동

 

  

  

CTRL+

SHIFT+

C

  

서식 복사

  

  

  

CTRL+

SHIFT+

V

  

서식 붙여넣기

  

  

보기

         

  

  

CTRL+

ALT+

N

  

기본 모양 보기

  

  

  

CTRL+

ALT+

O

  

개요 모양 보기

  

  

  

CTRL+

ALT+

P

  

인쇄 모양 보기

  

  

삽입

         

  

  

CTRL+

SHIFT+

F5

  

책갈피 넣기

  

  

  

CTRL+

ALT+

M

  

메모 넣기

  

  

  

CTRL+

 

Enter

  

페이지 나누기

  

  

  

CTRL+

SHIFT+

Enter

  

단 나누기

  

  

  

CTRL+

ALT+

D

  

미주 넣기

  

  

  

CTRL+

ALT+

F

  

각주 넣기

  

  

  

ALT+

SHIFT+

P

  

페이지 필드 넣기

 

  

  

ALT+

SHIFT+

T

  

시간 필드 넣기

  

  

  

  

F9

  

필드 업데이트하기

 

  

  

 

ALT+

F3

  

상용구 만들기

  

  

서식

         

  

  

CTRL+

 

D

  

글꼴 대화상자

  

  

  

CTRL+

 

B

  

굵게

   

  

  

CTRL+

 

I

  

이탤릭체

  

  

  

CTRL+

 

U

  

밑줄

   

  

  

CTRL+

SHIFT+

F

하고 Arrowkey

글꼴 바꾸기(toolbar에서)

  

  

CTRL+

SHIFT+

P

하고 Arrowkey

글꼴 크기 바꾸기(toolbar에서)

  

  

CTRL+

SHIFT+

S

하고 Arrowkey

스타일 바꾸기(toolbar에서)

  

  

CTRL+

SHIFT+

L

  

글머리꼴 넣기

  

  

  

CTRL+

 

M

  

들여쓰기

  

  

  

CTRL+

SHIFT+

M

  

내어쓰기

  

  

  

CTRL+

 

T

  

문장 첫글자 들여쓰기

 

  

  

CTRL+

SHIFT+

T

  

문장 첫글자 내어쓰기

 

  

  

CTRL+

 

]

  

글자 크기 늘리기

 

  

  

CTRL+

 

[

  

글자 크기 줄이기

 

  

  

CTRL+

 

J

  

양쪽 맞춤

  

  

  

CTRL+

 

E

  

가운데 맞춤

  

  

  

CTRL+

 

R

  

오른쪽 맞춤

  

  

  

CTRL+

 

L

  

왼쪽 맞춤

  

  

  

CTRL+

SHIFT+

D

  

균등분할 맞춤

  

  

  

CTRL+

 

=

  

윗첨자

   

  

  

CTRL+

 

+

  

아래첨자

  

  

  

CTRL+

SHIFT+

A

  

모두 대문자로

  

  

  

CTRL+

SHIFT+

K

  

소문자를 작은 대문자로

 

  

  

CTRL+

SHIFT+

N

  

표준 스타일 적용

 

  

  

CTRL+

ALT+

1

  

제목 1 스타일 적용

 

  

  

CTRL+

ALT+

2

  

제목 2 스타일 적용

 

  

  

CTRL+

ALT+

3

  

제목 3 스타일 적용

 

  

도구

         

  

  

  

한자키

  

한글 한자 변환

  

  

  

ALT +

SHIFT+

F7

      

  

  

 

ALT+

F8

  

매크로

   

  

  

 

SHIFT+

F7

  

영어 동의어 사전

 

  

  

 

ALT+

F7

  

다음 맞춤법이 틀리는 단어 찾기

  

         

  

  

  

Tab

  

셀 이동

   

  

  

 

Shfit+

화살표

  

셀 블록 설정

  

  

  

 

ALT+

Page Up

 

커서가 놓인 줄의 맨위 셀로

  

  

 

ALT+

Page Down

 

커서가 놓인 줄의 맨아래 셀로

  

  

 

ALT+

Home

  

커서가 놓인 줄의 맨 앞의 셀로

  

  

 

ALT+

End

  

커서가 놓인 줄의 맨 뒤 셀로

  

  

  

셀 선택후 Del

 

셀 안의 내용 지우기

 

  

         

  

  

 

ALT+

F10

  

워드를 전체화면으로 늘리기

  

  

 

ALT+

F5

  

문서를 전체화면으로 늘리기

  

  

CTRL+

ALT+

S

  

창 분할

   

  

도움말

         

  

  

  

F1

  

Help

   

  

  

 

SHIFT+

F1

  

설명(?)

   

  

  

CTRL+

 

F6

  

다음 창 띄우기

  

  

  

  

ALT+

Tap

  

  


'컴퓨터사용중' 카테고리의 다른 글

MS office 사용중 운영 체제 에러  (0) 2014.03.17
크롬에서 windows media 실행 안될 때.  (0) 2013.08.03
//
카테고리 없음 2013. 10. 10. 14:31

width:300px;

background:hsla(324,100%,50%,.9);

border:0.5em dotted rgba(0,0,0,4);

color:rgba(255,255,255,.8);

background-clip:padding-box;

border-radius:40px 0 50% 0;

box-shadow:10px 5px 10px black;

text-shadow: 1px .4em .3em black}

//
프로그래밍 2013. 8. 4. 22:21


1. 프로세스와 가상 메모리

모든 프로세스는 자신만의 가상 주소 공간을 가지고 있다.
32비트/64비트 프로세스는 각 비트수에 맞게 최대 4GB/16EB의 주소 공간을 가진다.

모든 프로세스들은 자신만의 주소 공간을 가지기 때문에,
특정 프로세스 내에서 쓰레드가 수행될 때 해당 쓰레드는 프로세스가 소유하고 있는 메모리에 대해서만 접근이 가능하다.
다른 프로세스에 의해 소유된 메모리는 숨겨져 있으며, 접근이 불가능하다.

윈도우에서는 운영체제 자체가 소유하고 있는 메모리 또한 숨겨져 있다.
이는 특정 프로세스의 수행 중인 쓰레드가 운영체제의 데이터에 접근하는 것이 불가능함을 의미한다.

따라서, A 프로세스가 0x12345678 주소에 무엇인가를 저장하였지만,
B 프로세스 역시 0x12345678 주소에 무엇인가를 저장할 수 있으며, 이 주소들은 완전히 독립되어 있는 것이다.

즉, 정리하면...

가상 메모리는 프로세스의 logical memory와 physical memory를 분리하기 위해 생겨난 것이라 할 수 있다.

이를 이용하여, logical memory가 physical memory보다 커지는 것을 가능케 할 수 있다.

하나의 프로세스 logical memory가 physical memory보다 커지는 것도 가능하며,
여러 프로세스의 logical memory 총합이 physical memory보다 커지는 것도 가능한 것이다.

램이 꼴랑 1기가인 PC를 생각해 보라.
이 PC에서 포토샵도 띄우고, 일러트스레이터도 띄으고, 3D 맥스도 띄운다.
느리다. 하드가 졸라 버벅대지만, PC는 멈추지 않고 돌아는 가게 된다.

이처럼, 프로세스가 실제 필요로 하는 부분만 메모리로 올리는 Demand-Paging 기법을 사용한다.
(이에 대해서는 아래에서 자세히 설명하겠다)

그렇다면, 포토샵도 띄우고, 3D 맥스도 띄웠는데 이 툴들의 작업 내용은 어디에 저장될까?
이미 메모리는 소진되고 없는데 말이다.

이를 기억해두기 위해 최근의 운영체제들은 디스크 공간을 메모리처럼 활용할 수 있는 기능을 가지고 있다.
디스크 상에 존재하는 이러한 파일을 paging file (또는 swap file)이라고 하며, 
모든 프로세스가 사용할 수 있는 가상 메모리로 사용된다.

용량 졸라 큰 게임을 실행하면 하드를 미친듯이 읽어댄다.
우리는 이것을 "하드 스왑 쩌네~"라고 표현하고...

여기서 말하는 하드 스왑이라는 페이징 파일에서 실제 물리 메모리로 올리고 내리고 하는 일련의 작업을 이야기하는 것이다.
(정식 명칭은 Disk thrashing이라고 하는데...이 역시 후반에 자세하게 설명하겠다)

애플리케이션 관점에서 보면, 페이징 파일을 사용하면 애플리케이션이 사용할 수 있는 램의 크기가 증가한 것과 같은 효과를 가져온다.
만일 PC에 4GB의 램이 있고, 디스크 상에 4GB의 페이징 파일이 있디면, 수행 중인 애플리케이션은 PC에 8GB의 램이 있는 것과 동일한 효과를 누릴 수 있는 것이다 (물론, 8GB 램보다는 4GB 램+ 4GB 페이징 파일이 더 느리겠지만)

자!
내용이 너무 길었다.
한번 더 정리하자.

한정된 물리 메모리의 한계를 극복하고자, 디스크와 같은 느린 저장장치를 활용해,
애플리케이션들이 더 많은 메모리를 활용할 수 있게 해 주는 것이 가상 메모리이다.


2. 프로세스 가상 주소 공간의 분할

각 프로세스의 가상 주소 공간은 분할되어 있으며, 각각의 분할 공간을 파티션(partition)이라고 한다.

주소 공간의 분할 방식은 운영체제의 구현 방식에 따라 서로 다를 수 있으며,
윈도우 계열에서도 커널이 달라지면, 그 구조가 조금씩 달라지곤 한다.

처음 32비트 프로세스는 4GB의 주소 공간을 가질 수 있다고 했다.
하지만, 사용자가 이 4GB를 모두 사용할 수 있는 것은 아니고, 약 2GB밖에 사용하지 못한다.
32비트 주소 공간이 아래와 같이 분할되어 있기 때문이다.
  • Null 포인터 할당 파티션 : 0x00000000 ~ 0x0000FFFF
  • 유저 모드 파티션 0x00010000 ~ 0x7FFEFFFF
  • 64KB 접근 금지 파티션 : 0x7FFF0000 ~ 0x7FFFFFF
  • 커널 모드 파티션 : 0x80000000 ~ 0xFFFFFFFF
1) Null 포인터 할당 파티션

프로그래머가 NULL 포인터 할당 연산을 수행할 경우를 대비하기 위해 준비된 영역이다.
만일 프로세스의 특정 쓰레드가 이 파티션에 대해 읽거나 쓰기를 시도하게 되면 접근 위반(access violation)이 발생한다.

2) 유저모드 파티션

프로세스의 주소 공간 내에서 유일하게 자유롭게 활용될 수 있는 파티션이다.
0x00010000 ~ 0x7FFEFFFF의 범위이므로, 2047MB의 크기이다.

모든 애플리케이션에 대해 프로세스가 유지해야 되는 대부분의 데이터가 저장되는 영역이며,
.exe / .dll 파일이 이 파티션에 로드된다.


3. Page

Page란, 가상 메모리를 사용하는 최소 크기 단위이다.
최근의 윈도우 운영체제는 모두 4096 (4KB)의 페이지 크기를 사용한다.

만약, 페이징 파일에서 물리 메모리로 데이터를 로드할 때, 
아무 위치에나 필요한 크기 만큼(무작위) 로드한다고 가정을 해 보자.

이런 경우, 로드하고 언로드하는 데이터의 크기가 모두 제각각이므로,
이를 반복하다 보면 메모리 공간에 fragmentation이 발생하게 된다.

결국 메모리는 남아 있지만, 정작 원하는 크기의 데이터를 물리 메모리로 로드하지 못하게 되는 상황이 생길 수 있는 것이다.

이를 막기 위해, 운영체제가 만든 것이 page라는 최소 크기 단위인 것이다.


4. Demanding-Page

Demanding-page는 실제로 필요한 page만 물리 메모리로 가져오는 방식을 이야기한다.

필요 page에 접근하려 하면, 결국 가상 메모리 주소에 대응하는 물리 메모리 주소를 찾아내어,
물리 메모리 주소를 얻어와 하는데, 이 때 필요한 것이 페이지 테이블(page table)이다.

페이지 테이블에 valid bit 라는 것을 두고, 해당 page가 물리 메모리에 있으면 set, 그렇지 않으면 invalid로 설정한다.

Page 접근 요청을 하였는데, physical memory에 없는 상태, 

즉 valid bit가 clear 되어있는 상황을 Page fault 라 하며 아래와 같은 처리 과정을 거친다.


1) 페이징 하드웨어는 page table entry를 보고 invalid인 것을 확인한 후 OS에게 trap으로 알린다.

2) OS는 정말로 메모리에 없는 것인지 아니면 잘못된 접근인지 확인한 후 잘못된 접근이었으면 종료시킨다.
3) Empty frame (free page)을 얻는다.
4) Page를 frame으로 swap한다.
5) 프로세스의 page table과 TLB를 page-in/page-out 된 것을 토대로 재설정한다.
6) Page fault를 야기했던 인스트럭션부터 다시 수행한다.


3번 과정에서 empty frame을 얻어와야 하는 상황에서 물리 메모리가 이미 모두 사용중이라면,
그 사용중인 frame 중 하나를 선택해서 page-out (페이징 파일로 이동) 시키고, 그 frame을 사용해야 한다.

이와 같이 victim frame을 선택하는 과정에서 Page Replacement Algorithm을 사용한다.


5. Page replacement alogorithm

페이지 교체 알고리즘은 꽤 다양한 종류가 있으며, 그 종류와 특징은 아래와 같다.

1. FIFO

가장 먼저 page-in 되어, 오래된 page를 page-out 시키는 방식.
단순하고 깔금하나, memory locality 측면에서 영 꽝이다.

2. LRU (Least Recent Used)

가장 오랫동안 사용되지 않았던 녀석은 앞으로도 사용되지 않을 것이라는 기대로 page-out 시키는 방식.
LRU는 두 가지 방식으로 보통 구현하는데,
  • 카운트 방식 : 4. Counting에서 이 방식을 쓴다.
  • 스택 방식 : 그 많은 페이지를 관리하기 위해, doubly-linked-list를 차용한 스택을 쓰기엔 메모리, 연산량이 너무 아깝다.
3. LRU approximation (이 방식이 굳)

LRU 개념이긴 하지만, 하드웨어의 도움을 받아 reference bit을 사용한다.
(레퍼런스 카운트 기법과 유사하다)

페이지들을 circular queue 형태로 나타내고 만약 reference가 일어나면 이 bit 를 set 한다. 
그리고 victim 페이지를 선정할 때는 하나씩 접근하여 reference bit 를 확인한다.
만약 bit 가 clear하면 그 페이지를 victim으로 선정하며, set 되어 있으면 그 bit 를 clear시키고 다음 페이지를 확인한다. 
해당 페이지에 Second-chance를 주는 것이므로 Second-chance algorithm이라고도 한다.

이 방식이 가장 많이 사용되고 효율이 좋은 것으로 알려져 있다.

4. Counting

Page가 참조될 때마다 카운팅을 하는 방식
  • MFU : Most frequent used
  • LFU : Least frequent used

6. Thrashing

가상 메모리를 사용하다 보면 실제 물리 메모리 공간보다 논리적 메모리 공간이 큰 것 처럼 사용될 수 있기 때문에 효율적이다. 

그런데, 효율적이라는 이유로 멀티 프로세싱의 degree를 계속 늘리다 보면, 
실제 실행하는 시간보다 page replacement를 하는 시간이 더 많아지는 순간이 오며, 결국엔 CPU 사용율이 떨어지게 된다. 
(하드가 미친듯이 돌아간다. 하드 스와핑이라고도 불리우는...)

이와 같이 프로그램을 제대로 수행하지 못하고, 실행 시간보다 페이지 교체 시간이 많아지는 현상을 Thrashing이라 한다.

이 thrashing이 발생하는 이유는 locality의 크기의 합이 실제 메모리의 크기보다 커졌기 때문이다.

따라서, 이 thrashing을 해결하기 위해서, Working set model 이란 것을 적용한다.
Working set model 은 locality 를 approximate한 것으로 페이지 넘버로 관리한다.
그러다 working set의 크기가 실제 메모리보다 커지면 하나의 프로세스를 종료하는 방식으로 thrashing이 생기지 않도록 할 수 있다.

하지만, 위 방법은 접근되는 페이지를 관리해야 하므로 불편한 감이 있다.
따라서, thrashing이 생겼다는 것은 즉, Page fault 가 많아졌다는 것이기 때문에
그것의 정도를 지정하고 Page fault 의 횟수가 어느 한계점을 넘어가면 프로세스를 종료하는 방식으로 구현한다.

무엇보다, Thrashing이 발생할 때 가장 좋은 솔루션은 램을 추가로 설치하는 것이다.


7. 가상 메모리의 부가 장점

가상 메모리를 사용하면서 생기는 부가 장점으로 다음과 같은 것들이 있다.
  • 공유 메모리 사용
  • Copy-on-write 메커니즘
  • Memory mapped file
위 장점들에 대해 하나씩 살펴보면...

1. 공유 메모리 사용

여러 프로세스 간의 communication의 한 가지 방법으로 공유 메모리를 사용할 수 있는데, 
demand-paging 기법을 사용할 경우 다른 프로세스의 각각의 페이지가 같은 프레임을 가리키도록 하면 공유 메모리를 사용할 수 있다.

윈도우의 dll이나 리눅스의 so 역시 이 방식으로 물리 메모리 프레임을 같이 가리키게 하여, 전체 메모리를 절약하게 되는 것이다.
아래 그림에서 프로세스 A의 1번 페이지, 프로세스 B의 7번 페이지가 물리 메모리 5번 프레임을 같이 가리키는 것을 볼 수 있다.


2. Copy-on-write 메커니즘

부모 프로세스를 clone하여 자식 프로세스를 생성하였을 때, 
처음에는 같은 메모리를 사용하도록 하다가 그곳에 Write가 발생하였을 때 메모리를 copy하는 것으로 
이것 또한 공유 메모리처럼 같은 프레임을 가리키도록 하였다가 복사가 되었을때 새로운 프레임을 할당하면 된다.


3. Memory mapped file

file을 접근하는 것을 메모리 접근하듯이 페이지를 할당하여 할 수 있도록 하는 것이며, 
메모리 접근 속도가 훨씬 더 빠르므로 효율적이라 할 수 있다.


'프로그래밍' 카테고리의 다른 글

git 명령어 및 이용  (0) 2014.03.23
Git 을 사용한 소스 버전관리  (0) 2014.03.17
IA32 레지스터에 관한 글-1  (0) 2013.08.04
이클립스 vim 플러그인  (0) 2012.12.08
이클립스 vim 플러그인  (0) 2012.12.01
//
프로그래밍 2013. 8. 4. 16:04

32bit cpu를 말합니다.

컴퓨터는 데이터를 저장하는 디바이스들이 여럿 있습니다. 잘 아시는 메모리(RAM) 하드, 등등. 

이는 계층 구조를 잘 이루고 있어서 각 계층에서 하는 역할이 있습니다. 이부분은 그냥 패스~

여기서는 cpu에 붙어서 기생? 하는 아주 작은 메모리 레지스터에 대한 이야기 입니다.

이러한 레지스터의 내용을 좀더 알기 위해서는 C언어가 아닌 어셈블리어를 이해해야 합니다. 어셈블리를 먼저 보신다면 반대. 어셈블리어는 대부분이 레지스터의 데이터를 조작하는 내용인데, 레지스터의 역할, 기능을 모르고서는 이해하기가 어렵죠 ㅠㅠ 이부분은 다음에 설명~

IA라고 했는데 intel architecture를 말하는 거에요. 32는 32비트 이다~ 그럼 요즘 64비트 컴퓨터가 많죠?

64비트 intel architecture는 ? IA64입니다. 컴퓨터 메모리는 저장되는 데이터가 여러개 이겠죠?  그런 데이터를 역할에 따라 저장되는 레지스터 종류가 있습니다. 

기본적인 프로그램 실행에 들어가는 레지스터에 대해 설명할게요

- Basic program execution registers -

이것은 다시 4개 그룹으로 나눕니다.

General purpose Register 32bit -8개

Segment Registers(16bit -6개)

Program Status and Control Registers(32bit -1개)

Instruction Pointer(32bit -1 개)

<Intel menual 참조>

General Purpose Register는 범용레지스터라고 해석이됩니다.  이 레지스터들은 32bit (4바이트)입니다.

보통 상수/주소등을 저장합니다.  이 레지스터들을 좀 자세히 보겠습니다. 

EAX : Accumulator for operands and results data

EBX : Pointer to data in the DS segment

ECX : Counter for string and loop operations

EDX : I/O pointer

이것들은 주로 산술연산(더하고,빼고,나누고) 에서 변수,상수값의 저장 용도로 쓰입니다. 

또 ECX는 반복문 의 카운터로 사용됩니다. 반복을 할 때마다 ECX의 값이 1씩 줄어듭니다. EAX는 함수의 리턴값을 저장합니다. win api들은 리턴값을 EAX에 저장합니다. EBX는 메모리 주소를 저장하기 위한 용도로 쓰입니다. EDX는 EAX와 같이 쓰이고 부호 확장명령에 쓰입니다. 큰 수의 곱셈 나눗셈의 연산이 이루어 질때 EAX와 같이 쓰입니다.


EBP : Pointer to data on the stack(in the SS segment)

ESI : source pointer for string operations

EDI : destination pointer for string operations

ESP : Stack pointer(in SS segment)

위의 4개는 주로 메모리 주소를 저장합니다.

ESP는 스택 메모리의 끝 주소를 가리킵니다. push, pop,call 은 ESP를 직접 조작한다. EBP는 스택 프레임의 시작 주소를 가리킵니다. EBP 레지스터는 현재 사용되는 스택 프레임이 소멸되지 않게 





'프로그래밍' 카테고리의 다른 글

git 명령어 및 이용  (0) 2014.03.23
Git 을 사용한 소스 버전관리  (0) 2014.03.17
프로세스와 메모리의 이야기  (0) 2013.08.04
이클립스 vim 플러그인  (0) 2012.12.08
이클립스 vim 플러그인  (0) 2012.12.01
//
Linux 2013. 8. 3. 22:52

logwatch - 정리된 시스템 로그 메일로 받기

 

logwatch 는 해당 로그 파일을 하루 단위로 종합적으로 정리를 해서 메일로 보내주는 데몬이다. 로그로 쌓이는 것을 다시 보기 좋게 재가공을 해서 다음날 메일로 받아 볼수 있게 된다. 

 

# logwatch 설치

 * 다운로드 

  http://www.logwatch.org >> logwatch-3.3-2.noarch.rpm 

 * 설치
 [root@cardsarang chtla]# rpm -Uvh logwatch-3.3-2.noarch.rpm 
  Preparing...                ########################################### [100%]
  1:logwatch               ########################################### [100%]
...

 

 * 설정 파일

 /etc/log.d/conf/logwatch.conf <== 설정 파일 
 /etc/log.d/scripts/logwatch.pl <== 크론에 의해 실행되는 파일(하루 한번)
 /etc/log.d/conf/services         <== 기록될 해당 서비스들을 각 설정을 세팅할수 있다.

                                                    디폴트로 사용하는 것도 무난하다.


 * 현재 지원되는 서비스
  arpwatch, automount, cron, dhcpd, exim, ftpd-messages, ftpd-xferlog, inentd, init, kernel,

  named, samba, sshd, sshd2 등이 있다.

 

 

# logwatch conf 설정

logwatch관련해서 conf파일은 /etc/log.d/logwatch.conf 파일이다. 이 파일에서 확인해 보아야 할것은 아래와 같이 두군데이다.

[root@chtla conf]# vi logwatch.conf 

LogDir = /var/log  <== 해당 로그 디렉토리
MailTo = root        <== 메일을 발송한 유저

혹시 메일 수신을 변경하려면 "MailTo" 부분을 다른 계정으로 변경하면 된다. 그러나, 이부분은 반드시 로컬계정만 가능하다.

 

만약, 일반 다른 메일로 보내고자 한다면, /etc/aliases 파일을 이용해서 보내야 한다. 아래 파일 내용을 보면 "root" 메일을 일반 다른 메일인 "webmaster@aaa.com"으로 보내게 처리했다.

[root@chtla conf]# vi /etc/aliase 
.....

# Person who should get root's mail
root:           webmaster@aaa.com

/etc/liases 파일을 수정하였다면 이를 적용하기 위하여 "newaliases" 명령어를 실행해 줘야 한다. 또한, sendmail이 설치되어 있어야 가능하며, 이부분에 대해서는 별도 공부하시기 바란다.

 

 

# 자동 메일 발송

설치후 달리 해 줄것이 없이 그냥 두면 크론(cront)에 의해 새벽 4시쯤에 로그 기록을 정리해 메일로 발송하게 된다.

[root@chtla scripts]# cd /etc/cron.daily/
[root@chtla cron.daily]# l
합계 9
lrwxrwxrwx   1 root  root     28  7월 15 16:57 00-logwatch -> ../log.d/scripts/logwatch.pl*
....

 


'Linux' 카테고리의 다른 글

Linux process explorer  (0) 2014.05.07
우분투 ssh 접속 시간 단축시키기  (0) 2014.04.09
tar를 이용한 백업  (0) 2013.02.12
시스템 백업과 복구  (0) 2013.01.29
리눅스에서 nfs(network file system)사용하기  (0) 2013.01.29
//
컴퓨터사용중 2013. 8. 3. 22:01

첨부된 파일을 받고 크롭 옵션에서 


설정 - 확장프로그램을 띄운뒤 확장프로그램창으로 파일을 드래그해서 옴기면 설치하게 된다.



'컴퓨터사용중' 카테고리의 다른 글

MS office 사용중 운영 체제 에러  (0) 2014.03.17
ms word 단축키  (0) 2013.10.14
//
프로그래밍/임베디드 2013. 7. 24. 20:05

vi edit의 모드

Command mode

Text의 위치나 편집 가능하게 함

Input mode

사용자가 text를 작성할 수 있는 모드


:q <enter>

to exit, if you have not made any changes to the file

:q! <enter>

the forced quit, it will discard the changes and quit

:wq <enter>

for save and Exit

:x <enter>

same as above command


To enter the text in vi you should first switch to input mode

•To switch to input mode there are several different commands

•a - Append mode places the insertion point after the current character

•i - Insert mode places the insertion point before the current character

•I - places the insertion point at the beginning of current line

•o - is for open mode and places the insertion point after the current line

•O - places the insertion point before the current line

•R - starts the replace(overwrite) mode


x - deletes the current character

d - is the delete command but pressing only d will not delete anything you need to press a second key

•dw - deletes to end of word

•dd - deletes the current line

•d0 - deletes to beginning of line


There are many more keys to be used with delete command

u - undo the changes made by editing commands

. - repeats the last edit command



Copy, cut and paste in vi

v - visual mode

yy - (yank) copy current line to buffer

nyy - where n is number of lines

p - paste the yanked lines from buffer to the line below

P - paste the yanked lines from buffer to the line above

(the paste commands will also work after yank)

gg - jump the first line of file

G - jump the end of file

nG - jump to the line (where n is line number)



'프로그래밍 > 임베디드' 카테고리의 다른 글

FlightGear Embedded board  (1) 2013.06.29
text lcd  (0) 2013.05.23
linux root filesystem  (0) 2013.05.23
7segment  (0) 2013.05.23
Led  (0) 2013.05.23
//