IT Japan
MySQL의 메모리 관계 본문
조금 전에 일어난 문제로 갑자기 시스템이 사용할 수 없게 된 것이 있었다.
조사한 결과, 아무래도 SQL 실행시 오류가 발생했습니다.
실제 로그에 나왔다 오류
Cause : com.mysql.jdbc.exceptions.MySQLSyntaxErrorException : Unknown table engine 'InnoDB'
라는 것.
왠지 InnoDB가없는 것으로 말하고있다.
조속히, Mysql에 로그인 후 show engines에서 엔진의 확인. 그러자
+ ------------ + --------- + -------------------------- --------------------------------- + -------------- + - --- + --------- +
| Engine | Support | Comment | Transactions | XA | Savepoints |
+ ------------ + --------- + -------------------------- --------------------------------- + -------------- + - --- + --------- +
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| MyISAM | DEFAULT | Default engine as of MySQL 3.23 with great performance | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
+ ------------ + --------- + -------------------------- --------------------------------- + -------------- + - --- + --------- +
물론, InnoDB가 없다. . . 왜 이래? ? ? 조속히 오류 로그에서 확인하면 다음과 같은 오류가.
InnoDB : Error : can not allocate 402669568 bytes of
InnoDB : memory with malloc! Total allocated memory
InnoDB : by InnoDB 45777564 bytes. Operating system errno : 12
InnoDB : Check if you should increase the swap file or
InnoDB : ulimits of your operating system.
InnoDB : On FreeBSD check you have compiled the OS with
InnoDB : a big enough maximum process size.
InnoDB : Note that in most 32-bit computers the process
InnoDB : memory space is limited to 2 GB or 4 GB.
InnoDB : We keep retrying the allocation for 60 seconds ...
InnoDB : Fatal error : can not allocate the memory for the buffer pool
아무래도 메모리가 부족해 mysqld는 떨어져 버린 것 같다.
메모리 관계는 잘 고려하여 설정했다려고했지만, 아무래도 실수가 있었던 것 같다. 그렇다고하는 것으로 조사 개시.
주로 도움이 된 것은 다음.
http://dic.birdlab.com/dic/17
http://dsas.blog.klab.org/archives/50860867.html
글쎄, 두 번째의 사이트는 가지고 있던 책과 동일한 내용이었다 하지만요. 초기 설정은 그 책을 참고했다.
다시 조사하여 메모리 사용량의 산출 방법 등의 존재는 알고 있었지만 생각하면 제대로 계산하지 않았구나.
또한 실패한 것이 두 눈 때문에 소개되고있는 mymemcheck (메모리 관련 검사 도구)을 제대로 실천하지 않았다.
이 도구는 참고 한 서적도 소개되어 있고, 시도했지만 쉽사리 움직이지 태국 めてた.
덧붙여서 어떤 오류인가하면 다음과 같은 느끼고.
# ./mymemcheck /etc/my.cnf
Can not locate Readonly.pm in @INC (@INC contains : /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.7/i386- linux-thread-multi /usr/lib/perl5/site_perl/5.8.6/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.5/i386-linux-thread-multi / usr / lib / perl5 / site_perl / 5.8.8
/usr/lib/perl5/site_perl/5.8.7
/usr/lib/perl5/site_perl/5.8.6
/usr/lib/perl5/site_perl/5.8.5
/ usr / lib / perl5 / site_perl
/usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.7/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8 0.6 / i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.5/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8
/usr/lib/perl5/vendor_perl/5.8.7
/usr/lib/perl5/vendor_perl/5.8.6
/usr/lib/perl5/vendor_perl/5.8.5
/ usr / lib / perl5 / vendor_perl
/usr/lib/perl5/5.8.8/i386-linux-thread-multi /usr/lib/perl5/5.8.8) at ./mymemcheck line 7.
BEGIN failed - compilation aborted at ./mymemcheck line 7.
지금 생각하면별로 대수롭지 않은 문제이다. 왜 당시 당해 않았을까 후회. . . 그럼 지금부터하자.
요점은 Readonly.pm를 찾을 수 없다는 오류이라 Readonly.pm을 준비지고있어 메시지의 어느 경로에 넣어 주면 좋다.
조속히, CPAN에서 필요한 모듈을 다운로드합니다.
이번 필요했던 것이 Readonly.pm과 UNIVERSAL :: require.pm 만에 끝났다.
그들을 /usr/lib/perl5/site_perl/5.8.8/ 바로 아래에 저장됩니다. (UNIVERSAL :: require.pm은 UNIVERSAL라는 디렉토리를 만들고 그 안에)
이제 잘 수행 할 수 있었다. 실행 결과를 조사했는데, 아무래도 max_connection의 수가 너무 많은 것 같았다. 그것을 좋은 상태로 조정했다.
결과는 이렇게되었다.
-------------------------------------------
global_buffers
key_buffer_size 67108864 64.000 [M]
innodb_buffer_pool_size 402653184 384.000 [M]
innodb_log_buffer_size 8388608 8.000 [M]
innodb_additional_mem_pool_size 41943040 40.000 [M]
net_buffer_length 64 64.000 []
thread_buffers
sort_buffer_size 1048576 1024.000 [K]
myisam_sort_buffer_size 67108864 64.000 [M]
read_buffer_size 1048576 1024.000 [K]
join_buffer_size 256 256.000 []
read_rnd_buffer_size 8388608 8.000 [M]
max_connections 100
min_memory_needed = global_buffers + (thread_buffers * max_connections)
= 520093760 + 77594880 * 100
= 4294967295 (7.711 [G])
[32bit Linux x86 limitation]
ref
* http://dev.mysql.com/doc/mysql/en/innodb-configuration.html
* need to include read_rnd_buffer.
* no need myisam_sort_buffer because allocate when repair, check alter.
2G> process heap
process heap = innodb_buffer_pool + key_buffer
+ max_connections * (sort_buffer + read_buffer + read_rnd_buffer)
+ max_connections * stack_size
= 402653184 + 67108864
+ 100 * (1048576 + 1048576 + 8388608)
+ 100 * 262144
= 1544552448 (1.438 [G])
2G> 1.438 [G] ... safe
[maximum size of innodb_log_file_size]
ref
* http://dev.mysql.com/doc/mysql/en/innodb-start.html
1MB <innodb_log_file_size <MAX_innodb_log_file_size <4GB
MAX_innodb_log_file_size = innodb_buffer_pool_size * 1 / innodb_log_files_in_group
= 402653184 * 1/2
= 201326592 (192.000 [M])
innodb_log_file_size <MAX_innodb_log_file_size
104857600 <201326592
100.000 [M] <192.000 [M] ... safe
-------------------------------------------------- -----
전체 견해는 그다지 모르겠지만,
key_buffer_size 67108864 64.000 [M]
왼쪽이 기준 값으로, 오른쪽이 실제 설정이라고 생각 것이다. 각 항목을보고 설정 값이 기준 값에 부합 있으면 좋다고 생각 것이다.
2G> 1.438 [G] ... safe
· safe라고 나와 있으니 분명 좋은 것이다.
또한 첫 번째 사이트에서 소개되고 있던 UNIX의 top 명령의 MySQL 버전 같은 도구 mytop라는 것도 넣어 보았다.
마지막으로, 스토리지 확인에서 InnoDB가 비활성화되어 있었으므로, ib_logfile과 ibdata 관련을 지우고 다시 시작했다.
그리고 백업 파일에서 DB를 복원하고 무사히 해결했다.
'MySQL' 카테고리의 다른 글
테이블 스페이스 확인 (0) | 2016.03.21 |
---|---|
【MySQL】 오류 해결 방법 (0) | 2016.03.21 |
MySQL에서 , 데이터베이스 사이즈 확인하는 방법 (0) | 2016.03.21 |
MySQL Parameter(my.cnf) 권장 값 (0) | 2016.03.21 |
MySQL StatList (0) | 2016.03.21 |