mysql - innodb 설정

DB/MySQL 2013. 11. 6. 11:52


다음은 MySQL InnoDB 관련 설정 변수이다. 

 

 

   [mysqld]

   innodb_data_home_dir="/MySQL/data/"
   innodb_log_group_home_dir="/MySQL/log"
   innodb_data_file_path=ibdata1:10M:autoextend:max:1000M
   innodb_autoextend_increment=8M

   innodb_additional_mem_pool_size=2M
   innodb_buffer_pool_size=512M
   innodb_flush_method=O_DIRECT
   innodb_flush_log_at_trx_commit=1
   innodb_log_file_size=80M
   innodb_log_buffer_size=2M
   innodb_log_archive=0
   innodb_thread_concurrency=8

 

 

 

innodb_data_file_path
Data File(Tablespace)의 속성을 정의한다.
[Data file path]파일명:파일크기:autoextend:max:파일최대크기;
파일 구분은 ';'이고 속성 구분은 ':'이다.

 

innodb_autoextend_increment
Data File(Tablespace)이 확장될 때 증가되는 Size(MB) (default=8M)

 

innodb_additional_mem_pool_size

default : 2M
Data Dictionary 정보를 보관하기 위한 Memory Size.

innodb_buffer_pool_size
default : 8M
index 및 raw data Cache 용 Memory Size를 의미하며 Maximum Size는 Real Memory의 80%까지 정의 가능하다. 하지만, Memory Paging을 최소화 할 수 있는 Size가 적당하다. 참고로 Oracle의 권고 SGA Size는 Real Memory의 50%이다. 32 Bit O/S의 경우 Addressing 특성 상 Maximum 4G이므로 O/S 및 다른 용도의 Memory를 감안하여 이보다 작게 정의해야 한다.

 

innodb_flush_method
Disk I/O Buffer의 사용 여부.
일 반적으로 Disk I/O가 발생하면 그 즉시 Disk에 반영되지 않고 Memory에 Caching되었다가 일정 Size이상이 되면 그 때 Disk에 Physically 반영되는데, 이러한 과정 없이 즉시로 Disk에 반영 시키는 Option이다.
[O_DIRECT] Cache Write 시 Disk에도 동일하게 반영 시킨다.

[O_DSYNC

 

innodb_flush_log_at_trx_commit
Commit 시 Commit Log를 Log File에 어떻게 기록할지를 지정한다.
[0] Log Buffer가 꽉 차거나 Flush Log가 발생할때 Log File에 기록
[1] Commit이 발생할 때 마다 Log File에 기록
[2] 1초마다 Log File에 기록

 

innodb_log_file_size
트랜잭션을 기록하는 로그 파일의 크기를 결정하는 옵션으로  로그파일은 무한정 계속 커지는 것이 아니라 일정한 크기와 갯수를 가지고 순환식으로 처리된다.
보통 일반적으로 innodb_buffer_pool_size 의 15% 정도로 설정한다.
만약 메모리가 1GB이면 innodb_buffer_pool_size = 512M 이고, innodb_log_file_size = 80M 이다.

 

innodb_log_buffer_size
로그 파일을 기록하기 위한 Buffer Size로 Transaction이 작거나 거의 없다면 크게 잡는것은 낭비이다.
보통 1M~8M 사이로 설정.

 

innodb_log_archive
Log File의 Archive화 여부로 복구 시 Log File을 사용하므로 설정할 필요가 없음.


innodb_file_per_table
Table 마다 별도의 Data File을 가지게하는 옵션으로 하나의 Tablespace에는 하나의 Table Data만 저장한다. 단, 단점은 Data와 Index가 동일 Tablespace(Data File)에 저장된다는 것이다.



출처 - http://aladdin07.blog.me/150137340778







1. MyISAM



1) 예전의 MySQL 의 Storage Engines 으로 MyISAM 을 사용했었습니다.

    예를 들자면 블로그라던지, 게시판 처럼 한사람이 글을 쓰면 다른 많은 사람들이 글을 읽는 방식에

    최적의 성능을 발휘를 하지요. 지금도 많이 사용하고 있는 방식입니다.



2) 제공하는 웹서비스다 그닥 크지 않다면 이것을 사용해도 괜찮다고 생각을 합니다.





2. InnoDB



1) 트랜잭션-세이프 스토리지 엔진입니다.



2) MyISAM 과 비슷하지만 ORACLE 처럼 많은 기능을 지원을 합니다.

   (* commit, rollback, 장애복구, row-level locking, 외래키 등)



3) 다수의 사용자 동시접속과 퍼포먼스가 증가하여 대용량 데이터를 처리할 때 최대의 퍼포먼스를 내도록 설계되었습니다.
   CPU효율은 어느 디스크 기반의 데이터 베이스와 비교해도 손색이 없고
   자체적으로 메인 메모리 안에 데이터 캐싱과 인덱싱을 위한 버퍼 풀(pool)을 관리합니다.

4) 테이블과 인덱스를 테이블 스페이스에 저장을 하고 테이블 스페이스는 몇개의 서버파일이나 디스크 파티션으로

   구성되어있습니다. 이것은 MyISAM 과 다른 점인데, MyISAM은 테이블과 인덱스를 각각 분리된 파일로 관리합니다.

   여기서 중요한것이 이제 InnoDB 를 제대로 사용을 하기 위해서는 테이블 스페이스 라는 개념을 파악을 하셔야합니다.
   이것에 대해서는 밑에서 따로 언급을 하겠습니다.


5) InnoDB 테이블은 OS의 파일 사이즈 한계가 2GB이더라도 상관없이 어느 크기나 가질 수 있습니다.

6) InnoDB는 높은 퍼포먼스가 필요한 대용량 사이트에 적합합니다.





3. InnoDB 사용하기



1) InnoDB 는 MyISAM 과 공유하는 메모리도 있지만 별도의 Buffer pool을 가지고 있으니까

   InnoDB 전용 DB를 구성한다면 MyISAM 이 사용하는 record_boffer 과 key_buffer 에 너무 많은 메모리를 할당하지 마세요

  
2) InnoDB 설정
   ㄱ) MySql 을 설치한 폴더 아래에 ibdata 와 iblogs 폴더를 생성합니다.
   ㄴ) my.ini 파일 설정을 변경
      * innodb_buffer_pool_size

        - 현재 자신의 시스템 메모리의 50~80% 사이로 만듭니다.

           x86 시스템에서는 2G 이상 설정을 할 수 없습니다.

      * innodb_additional_mem_pool_size

        - 데이터 사전정보 나 내부의 데이터 구조 정보를 담는 메모리 입니다.

           보통 2M 정도 잡아주면 아주 많은 테이블을 사용한다면 좀 늘려주시면 됩니다.

           만약 메모리공장이 부족하면 error log 에 warning 메서지를 남기니 그때 늘려주세요

      * innodb_flush_log_at_trx_commit

        - insert, update 등 데이터 삽입과 관계가 있습니다.

           commit 을 하였을때 그 즉시 commit 된 데이터를 log file 에 기록할지 안할지를 설정합니다.

           로그파일을 기록할 경우 갑작스러운 경우 데이터 손실을 막을 수 있지만 매번 로그를 기록하므로 속도가 저하됩니다.

           1 일경우 기록을 하는것이고, 0일 경우 기록을 안하는것입니다.

      * innodb_log_file_size

        - 트랜잭션을 기록하는 로그 파일의 크기를 결정하는 옵션입니다.

           inno_buffer_pool_size 옵션은 성능을 위한것이지만 시스템이 다운되었을 경우 데이터가 손실이 되므로

           이것을 방지하기 위해 log file 을 만들어서 commit 될때마다 로그에 기억을 하고 자동복구를 합니다.

           로그파일은 무한정 계속 커지는 것이 아니라 일정한 크기와 갯수를 가지고 순환식으로 처리되므로 크기는

           inno_buffer_pool_size 의 15% 정도로 설정을 합니다.

           만약 메모리가 1기가이면 inno_buffer_pool_size = 512M 이고, innodb_log_file_size = 80M 가 됩니다.

      * innodb_log_buffer_size

        - 로그 파일을 기록하기 위한 버퍼 사이즈입니다.

          트랜잭션이 작거나 거의 없다면 크게 잡는것은 낭비이므로 보통 1M~8M 사이로 설정을 합니다.



      [mysqld]

      innodb_data_home_dir="C:/MySQL/MySQL Server 5.0/ibdata/"
      innodb_log_group_home_dir="C:/MySQL/MySQL Server 5.0/iblogs"
      innodb_data_file_path=ibdata1:10M:autoextend:max:1000M
      innodb_additional_mem_pool_size=3469K
      innodb_flush_log_at_trx_commit=1
      innodb_log_buffer_size=2M
      innodb_buffer_pool_size=256M
      innodb_log_file_size=40M
      innodb_thread_concurrency=8
      innodb_log_archive=0


   ㄷ) my.ini 을 수정했으면 mysql 서버를 재시작합니다.

3) InnoDB 테이블 만들기
   create table test_inno (

   ~

   )type=innodb;

   으로 맨 마지막에 type=innodb; 라고 명시해주시면 됩니다.

4) InnoDB 트랜잭션 사용
  ㄱ) 트랜잭션을 사용하기 위해서는 처음에 set autocommit=0; 이나 begin; 을 선언해야 합니다.

      선언 후 데이터 변경이 있을 때, 이상이 없을 경우는 commit를 하고, 이상이 있을 경우 rollback을 실행합니다.
      오라클이랑 비슷하다고 보시면 되요

      mysql>set autocommit=0; //begin; 같음
      mysql>insert into test_inno values (1,'aaa');
      mysql>select * from test_inno; //현재창에서는 입력한 내용이 보이지만 다른창에서는 보이지않음
      mysql>commit; //다른창에서 select를 할경우 입력한 값이 보임





4. InnoDB 테이블 스페이스

좀전에 MyISAM 과 차이점이 InnoDB 는 테이블과 인덱스를 테이블 스페이스 라는곳에 저장을 한다고 하였습니다.

그런데 사용을 하다보니 점차 DB가 늘어나서 테이블 스페이스가 FULL 이 발생하는 경우가 생깁니다.



4.0.x 버전부터는 일일이 할 필요가 없다는 글이 있는데 그래도 FULL이 발생하였을 때 대처방법을 알면 좋겠죠



my.ini 에서 아래와 같이 추가를 해주면 안됩니다.

innodb_data_file_path = /ibdata/ibdata1:1000M:autoextend 라고 할 경우

innodb_data_file_path = /ibdata/ibdata1:1000M;/ibdata/ibdata2:1000M:autoextend 라고 ibdata2를 추가하면 안됩니다.



아래와 같은 과정대로 하세요

1. Use mysqldump to dump all your InnoDB tables.

2. Stop the server.

3. Remove all the existing tablespace files.

4. Configure a new tablespace.

5. Restart the server.

6. Import the dump files.



즉, 일단 mysqldump 로 InnoDB 테이블의 전체 덤프뜬 다음 MySQL 서버를 중지시킵니다.

그다음 테이블스페이스 파일을 모두 지우고 테이블스페이스를 아래와 같이 추가를 합니다.

innodb_data_file_path = /ibdata/ibdata1:1000M;/ibdata/ibdata2:1000M:autoextend

그다음 MySQL 서버를 구동시킨다음 처음에 덤프뜬 파일을 import 하시면 됩니다.





5. 마지막으로

위의 단계처럼 참 어렵게 설정을 하였지만, mysql.com 사이트에 들러보시면 MySQL GUI Tools 라는 프로그램이 있습니다.

물론 무료로 다운로드 가능하고요, 이 프로그램을 설치를 하면 MySQL Administrator 라는 것이 있는데 이것을 통해서

아주 쉽게 MySQL 의 설정을 변경하실 수 있습니다.



출처 - http://czar.tistory.com/263







출처 - 도서 High Performance MySQL: Optimization, Backups, and Replication p364














'DB > MySQL' 카테고리의 다른 글

mysql - InnoDB, Innobase  (0) 2013.11.06
mysql - innodb 용량 늘리기  (0) 2013.11.06
mysql - innodb ibdata1 archetecter  (0) 2013.11.06
mysql - 권한 정보 테이블(user, db)  (0) 2013.11.01
mysql - 한글 정렬  (0) 2013.05.14
Posted by linuxism
,


What is the ibdata1 file in my /var/lib/mysql directory?


Logging in to my Webmin control panel, I noticed that virtually all of my disk space is full. I searched for the ten largest files/ directories on my system and found that a file called ibdata1 is taking up around 94GB of space. It resides in my /var/lib/mysql directory.

What does ibdata1 do? Am I safe to remove it? My assumption is that it's a dump of some kind, but that's just a wild guess.


The file ibdata1 is the system tablespace for the InnoDB infrastructure.

It contains several classes for information vital for InnoDB

  • Table Data Pages
  • Table Index Pages
  • Data Dictionary
  • MVCC Control Data
    • Undo Space
    • Rollback Segments
  • Double Write Buffer (Pages Written in the Background to avoid OS caching)
  • Insert Buffer (Changes to Secondary Indexes)
  • Click Here to see a Pictorial Representation

You can separate Data and Index Pages from ibdata1 by enabling innodb_file_per_table. This will cause any newly created InnoDB table to store data and index pages in an external .ibd file.

Example

  • datadir is /var/lib/mysql
  • CREATE TABLE mydb.mytable (...) ENGINE=InnoDB;, creates/var/lib/mysql/mydb/mytable.frm
    • innodb_file_per_table enabled, Data/Index Pages Stored in/var/lib/mysql/mydb/mytable.ibd
    • innodb_file_per_table disabled, Data/Index Pages Stored in ibdata1

No matter where the InnoDB table is stored, InnoDB's functionality requires looking for table metadata and storing and retrieving MVCC info to support ACID compliance and Transaction Isolation.

Here are my past articles on separating table data and indexes from ibdata1

WHAT TO DO NEXT

You can continue having ibdata1 stored everything, but that makes doing LVM snapshots real drudgery (my personal opinion).

You need to use My StackOverflow post and shrink that file permanently.

Please run this query:

SELECT 
    ((POWER(1024,3)*94 - InnoDBDiskDataAndIndexes))/POWER(1024,3) SpaceToReclaim
FROM
(SELECT SUM(data_length+index_length) InnoDBDiskDataAndIndexes
FROM information_schema.tables WHERE engine='InnoDB') A;

This will tell how much wasted space can be reclaimed after applying the InnoDB Cleanup.

share|improve this answer
 
Thanks for your input. My disk quota has since filled completely - before I act on any of the advice in your posts, will I need free space? I note that your original post on SO mentions about doing an SQL dump, but this would presumably create a ~90GB file with nowhere to go. –  James Mar 13 at 22:21
 
mysqldump will only the logical representation of the data pages, not the indexes. You will need another disk mount, perhaps a remote server, to dump the data. –  RolandoMySQLDBA Mar 14 at 3:18


출처 - http://serverfault.com/questions/487159/what-is-the-ibdata1-file-in-my-var-lib-mysql-directory








출처 - http://www.scribd.com/doc/31337494/XtraDB-InnoDB-internals-in-drawing








출처 - http://intomysql.blogspot.kr/2010/12/innodb_9912.html












'DB > MySQL' 카테고리의 다른 글

mysql - innodb 용량 늘리기  (0) 2013.11.06
mysql - innodb 설정  (0) 2013.11.06
mysql - 권한 정보 테이블(user, db)  (0) 2013.11.01
mysql - 한글 정렬  (0) 2013.05.14
mysql 클러스터(cluster)  (0) 2013.03.08
Posted by linuxism
,

c - waitpid() 함수

Development/C 2013. 11. 3. 13:16


설명

wait()함수처럼 자식 프로세스가 종료될 때까지 대기합니다. 차이점은 wait() 함수가 자식 프로세스 중 어느 하나라도 종료되면 복귀되지만, 즉 대기에서 풀리지만 waitpid()는 특정 자식 프로세스가 종료될 때까지 대기 합니다.

또한 wait()는 자식 프로세스가 종료될 때까지 block되지만 waitpid()는 WNOHANG 옵션을 사용하면 block되지 않고 다른 작업을 진행할 수 있습니다.

pid_t waitpid(pid_t pid, int *status, int options);

첫번째 인수 pid_t pid는 감시 대상인 자식 프로세스의 ID입니다. 이 ID값에는 자식 프로세스 ID외에도 아래와 같은 값을 지정할 수 있습니다.

pid설명
-1여러 자식 중 하나라도 종료되면 복귀, wait()와 같은 처리
0현재의 프로세스의 그룹 ID와 같은 그룹의 자식 프로세스가 종료되면 복귀
양수pid에 해당하는 자식 프로세스가 종료되면 복귀

3번재 인수 options는 여러 상수 값이 있습니다만 WNOHANG와 0을 많이 사용합니다.

options설명
WNOHANG자식 프로세스가 종료되었는지 실행 중인지만 확인하고 바로 보귀. 즉, 부모프로세스는 bock되지 않음
0자식 프로세스가 종료될 때까지 block됨. 즉, wait()와 같은 처리

WNOHANG를 사용했을 경우 waitpid()는 자식 프로세스의 종료 상태를 확인하고 바로 복귀합니다. 만일 자식 프로세스가 활동 중이라면 0을 반환하고, 종료되면 자식 프로세스의 ID가 반환됩니다.

헤더wait.h
형태pid_t waitpid(pid_t pid, int *status, int options);
인수pid_t pid감시할 자식 프로세스 ID
 int *status자식 프로세스의 종료 상태 정보
 int options대기를 위한 옵션
반환int

정상: 종료된 자식 프로세스 ID
실패: -1
WNOHANG를 사용했고 자식 프로세스가 종료되지 않았다면: 0

예제

예제를 두가지 올립니다. 첫번째 예제는 두번째 생성한 자식 프로세스가 종료될 때까지 대기하도록 하며, 두번째 예제는 자식 프로세스가 종료될 때까지 부모 프로세스도 제 할일을 하도록 하겠습니다.

첫번째 예제입니다. 두개의 자식 프로세스를 생성하는데, 첫번째 자식 프로세스는 5까지 카운트하고 두번째 자식 프로세스는 10까지 카운트합니다. 부모 프로세스는 10까지 카운트하는 자식 프로세스가 종료될 때 까지 대기합니다.

#include <stdio.h>
#include <unistd.h>
#include <wait.h>

int main()
{
   int   counter  = 1;
   int   status;
   pid_t pid;
   pid_t pid_child;
       
   printf( "부모: 첫번째 자식 프로세스를 생성합니다.\n");    
   pid   = fork();

   switch( pid)
   {
      case -1  :
      {
         printf( "자식 프로세스 생성 실패\n");
         return -1;
      }
      case 0   :
      {
         printf( "1st: 저는 첫번째 자식 프로세스로 5까지 카운트하고 종료하겠습니다.\n");
         while( 6 > counter )
         {
            printf( "1st: %d\n", counter++);
            sleep( 1);
         }
         return 99;
      }
      default  :
      {
         printf( "부모: 두번째 자식 프로세스를 생성합니다.\n");    
         pid   = fork();
      
         switch( pid)
         {
            case -1  :
            {
               printf( "자식 프로세스 생성 실패\n");
               return -1;
            }
            case 0   :
            {
               printf( "2nd: 저는 두번째 자식 프로세스로 10까지 카운트하고 종료하겠습니다.\n");
               while( 11 > counter )
               {
                  printf( "2nd: %d\n", counter++);
                  sleep( 1);
               }
               return 99;
            }
            default  :
            {
               printf( "부모: 저는 부모 프로세스로 자식 프로세스 작업이 \
끝날 때 까지 대기합니다..\n");
      
               pid_child   = waitpid( pid, &status, 0);
      
               printf( "부모: 종료된 자식 프로세스 ID는 %d이며,", pid_child);
               if ( 0 == ( status & 0xff))
               {
                  printf( "정상적으로 종료되었고 반환값은 %d입니다\n", status >> 8);
               }
               else
               {
                  printf( "비 정상으로 종료되었고 종료 시그널 번호는 %d입니다\n", status);
               }
               printf( "이제 제일을 처리하겠습니다.\n");
      
               while( 1 )
               {
                  printf( "부모: %d\n", counter++);
                  sleep( 1);
               }
            }
         }
      }
   }
}
]$ ./a.out
부모: 첫번째 자식 프로세스를 생성합니다.
1st: 저는 첫번째 자식 프로세스로 5까지 카운트하고 종료하겠습니다.
1st: 1
부모: 두번째 자식 프로세스를 생성합니다.
2nd: 저는 두번째 자식 프로세스로 10까지 카운트하고 종료하겠습니다.
2nd: 1
부모: 저는 부모 프로세스로 자식 프로세스 작업이 끝날 때 까지 대기합니다..
1st: 2
2nd: 2
1st: 3
2nd: 3
1st: 4
2nd: 4
1st: 5
2nd: 5
2nd: 6
2nd: 7
2nd: 8
2nd: 9
2nd: 10
부모: 종료된 자식 프로세스 ID는 5845이며,정상적으로 종료되었고 반환값은 99입니다
이제 제일을 처리하겠습니다.
부모: 1
부모: 2
부모: 3
부모: 4
:

이번에는 WNOHANG 옵션을 사용하여 부모 프로세스가 block되지 않고 자식 프로세스의 종료 상태를 확인하는 예제입니다.

#include <stdio.h>
#include <unistd.h>
#include <wait.h>

int main()
{
   int   counter  = 1;
   int   status;
   pid_t pid;
   pid_t pid_child;

   printf( "부모: 첫번째 자식 프로세스를 생성합니다.\n");
   pid   = fork();

   switch( pid)
   {
      case -1  :
      {
         printf( "자식 프로세스 생성 실패\n");
         return -1;
      }
      case 0   :
      {
         printf( "1st: 저는 첫번째 자식 프로세스로 5까지 카운트하고 종료하겠습니다.\n");
         while( 6 > counter )
         {
            printf( "1st: %d\n", counter++);
            sleep( 1);
         }
         return 99;
      }
      default  :
      {
         printf( "부모: 두번째 자식 프로세스를 생성합니다.\n");
         pid   = fork();

         switch( pid)
         {
            case -1  :
            {
               printf( "자식 프로세스 생성 실패\n");
               return -1;
            }
            case 0   :
            {
               printf( "2nd: 저는 두번째 자식 프로세스로 10까지 카운트하고 종료하겠습니다.\n");
               while( 11 > counter )
               {
                  printf( "2nd: %d\n", counter++);
                  sleep( 1);
               }
               return 99;
            }
            default  :
            {
               printf( "부모: 저는 부모 프로세스로 자식 프로세스 작업이 \
종료되었는지 확인하면서 제일을 하겠습니다.\n");

               while( 1 )
               {
                  printf( "부모: %d\n", counter++);
                  pid_child   = waitpid( pid, &status, WNOHANG);
                  if ( 0 != pid_child)
                  {
                     printf( "자식 프로세스가 종료되었습니다.\n");
                  }
                  sleep( 1);
               }
            }
         }
      }
   }
}

]$ ./a.out
부모: 첫번째 자식 프로세스를 생성합니다.
1st: 저는 첫번째 자식 프로세스로 5까지 카운트하고 종료하겠습니다.
1st: 1
부모: 두번째 자식 프로세스를 생성합니다.
2nd: 저는 두번째 자식 프로세스로 10까지 카운트하고 종료하겠습니다.
2nd: 1
부모: 저는 부모 프로세스로 자식 프로세스 작업이 종료되었는지 확인하면서 제일을 하겠습니다.
부모: 1
1st: 2
2nd: 2
부모: 2
1st: 3
2nd: 3
부모: 3
1st: 4
2nd: 4
부모: 4
1st: 5
2nd: 5
부모: 5
2nd: 6
부모: 6
2nd: 7
부모: 7
2nd: 8
부모: 8
2nd: 9
부모: 9
2nd: 10
부모: 10
부모: 11
부모: 12
자식 프로세스가 종료되었습니다.
부모: 13
자식 프로세스가 종료되었습니다.
부모: 14
자식 프로세스가 종료되었습니다.
부모: 15
자식 프로세스가 종료되었습니다.
부모: 16
자식 프로세스가 종료되었습니다.
부모: 17
자식 프로세스가 종료되었습니다.


출처 - http://forum.falinux.com/zbxe/?mid=C_LIB&page=3&document_srl=408548





'Development > C' 카테고리의 다른 글

c - return vs exit  (0) 2016.03.16
c - execlp() 함수  (0) 2013.11.03
c - pid_t  (0) 2013.11.03
c - 메모리 맵(memory map)  (1) 2013.08.30
c - 구조체  (0) 2013.04.26
Posted by linuxism
,