
120GB RAM이 장착된 Ubuntu 12.04 서버에서 실행되는 MySQL 인스턴스가 있습니다. 여기에는 때때로 새로운 mysql 매개변수를 설정하는 여러 PHP 스크립트가 실행되고 있습니다. 이러한 스크립트 중 하나는 대규모 MEMORY 테이블을 사용하여 데이터를 MySISAM 테이블에 삽입하기 전에 통합합니다.
최근에 "테이블이 꽉 찼습니다" 오류를 방지하기 위해 max_heap_table_size 및 tmp_table_size를 16GB에서 20GB로 업데이트했습니다. 결과적으로 다음 스크립트 실행 중에 MySQL이 충돌했습니다.
실제로 먼저 strack 추적을 생성했습니다.
14:30:19 UTC - mysqld got signal 11 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
We will try our best to scrape up some info that will hopefully help
diagnose the problem, but since we have already crashed,
something is definitely wrong and this may fail.
key_buffer_size=536870912
read_buffer_size=131072
max_used_connections=85
max_threads=700
thread_count=82
connection_count=81
It is possible that mysqld could use up to
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 2055554 K bytes of memory
Hope that's ok; if not, decrease some variables in the equation.
Thread pointer: 0x7ff66dbb4f30
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 7ff632b80e60 thread_stack 0x28000
/usr/sbin/mysqld(my_print_stacktrace+0x29)[0x7ff66b087589]
/usr/sbin/mysqld(handle_fatal_signal+0x483)[0x7ff66af4c9d3]
/lib/x86_64-linux-gnu/libpthread.so.0(+0xfcb0)[0x7ff669c96cb0]
/usr/sbin/mysqld(_Z10field_convP5FieldS0_+0x37)[0x7ff66af49077]
/usr/sbin/mysqld(_ZN10Item_field13save_in_fieldEP5Fieldb+0x46)[0x7ff66af599b6]
/usr/sbin/mysqld(_Z11fill_recordP3THDPP5FieldR4ListI4ItemEb+0x4e)[0x7ff66adf3afe]
/usr/sbin/mysqld(_ZN12select_union9send_dataER4ListI4ItemE+0x6f)[0x7ff66aea705f]
/usr/sbin/mysqld(+0x32c554)[0x7ff66ae5a554]
/usr/sbin/mysqld(+0x3225cf)[0x7ff66ae505cf]
/usr/sbin/mysqld(_Z10sub_selectP4JOINP13st_join_tableb+0x7e)[0x7ff66ae5255e]
/usr/sbin/mysqld(+0x335274)[0x7ff66ae63274]
/usr/sbin/mysqld(_ZN4JOIN4execEv+0xc03)[0x7ff66ae72ec3]
/usr/sbin/mysqld(_Z12mysql_selectP3THDPPP4ItemP10TABLE_LISTjR4ListIS1_ES2_jP8st_orderSB_S2_SB_yP13select_resultP18st_select_lex_unitP13st_select_lex+0x130)[0x7ff66ae6e610]
/usr/sbin/mysqld(_Z21mysql_derived_fillingP3THDP3LEXP10TABLE_LIST+0x121)[0x7ff66ae13671]
/usr/sbin/mysqld(_Z20mysql_handle_derivedP3LEXPFbP3THDS0_P10TABLE_LISTE+0x68)[0x7ff66ae130f8]
/usr/sbin/mysqld(_Z20open_and_lock_tablesP3THDP10TABLE_LISTbjP19Prelocking_strategy+0x11a)[0x7ff66adf7c9a]
/usr/sbin/mysqld(+0x2fac95)[0x7ff66ae28c95]
/usr/sbin/mysqld(_Z21mysql_execute_commandP3THD+0x16a6)[0x7ff66ae307f6]
/usr/sbin/mysqld(_Z11mysql_parseP3THDPcjP12Parser_state+0x10f)[0x7ff66ae35a0f]
/usr/sbin/mysqld(_Z16dispatch_command19enum_server_commandP3THDPcj+0x1e71)[0x7ff66ae37951]
/usr/sbin/mysqld(_Z24do_handle_one_connectionP3THD+0x1bd)[0x7ff66aeddd9d]
/usr/sbin/mysqld(handle_one_connection+0x50)[0x7ff66aedde00]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x7e9a)[0x7ff669c8ee9a]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x6d)[0x7ff6693bf3fd]
Trying to get some variables.
Some pointers may be invalid and cause the dump to abort.
Query (7fea98004a80): is an invalid pointer
Connection ID (thread ID): 15144
Status: NOT_KILLED
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains
information that should help you find out what is causing the crash.
충돌/다시 시작은 한 시간 후에 발생했습니다.
131122 15:30:24 [Warning] Using unique option prefix myisam-recover instead of myisam-recover-options is deprecated and will be removed in a future release. Please use the full name instead.
131122 15:30:24 [Warning] Using unique option prefix myisam-recover instead of myisam-recover-options is deprecated and will be removed in a future release. Please use the full name instead.
131122 15:30:24 [Note] Plugin 'FEDERATED' is disabled.
131122 15:30:24 InnoDB: The InnoDB memory heap is disabled
131122 15:30:24 InnoDB: Mutexes and rw_locks use GCC atomic builtins
131122 15:30:24 InnoDB: Compressed tables use zlib 1.2.3.4
131122 15:30:24 InnoDB: Initializing buffer pool, size = 128.0M
131122 15:30:24 InnoDB: Completed initialization of buffer pool
131122 15:30:24 InnoDB: highest supported file format is Barracuda.
InnoDB: Log scan progressed past the checkpoint lsn 1319218667
131122 15:30:24 InnoDB: Database was not shut down normally!
InnoDB: Starting crash recovery.
불행하게도 여기에 게시할 binlog 또는 느린 쿼리 로그 출력이 없지만 제가 말할 수 있는 것은 스택 추적이 생성된 후에도 PHP 스크립트가 계속 실행되었다는 것입니다. mysql을 다시 시작하는 동안 중지되었습니다.
이 오류는 이미 2개의 개별 서버에서 발생했으므로 하드웨어 오류를 고려해서는 안 됩니다.
충돌의 원인은 무엇일까요? mysql을 충돌시키지 않고 사용할 수 있는 최대 max_heap_table_size 및 tmp_table_size를 어떻게 알 수 있습니까?
ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 1031141
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 1031141
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
Ubuntu 12.04,1의 경우 mysql 버전은 5.5.34입니다.
답변1
120GB의 메모리를 사용하면 컴퓨터에 여러 개의 물리적 CPU와 NUMA(Non-Uniform Memory Access) 아키텍처가 있을 수도 있습니다. 그렇다면 사용 가능한 메모리가 충분할 수 있지만 여전히 반직관적으로는 사용 가능한 메모리가 부족합니다.
지금까지 순조롭게 진행 중이라면 MySQL이 테이블에 할당된 메모리를 늘리려고 시도할 때 이 문제가 발생할 수 있으며 MEMORY
, 이 아키텍처에서 실행될 때 Linux가 메모리 할당을 처리하는 방식과 관련된 오류가 발생했을 수 있습니다. 마더보드의 다른 곳에서 사용 가능한 다른 물리적 메모리가 있음에도 불구하고 메모리 요청이 처리되는 "하나"로 임의로 선택된 하나의 특정 CPU에 직접 연결된 메모리 스틱에 있는 사용 가능한 메모리를 고려합니다. .
NUMA는 이론적으로는 괜찮지만 MySQL의 경우처럼 대량의 메모리가 필요한 단일 프로세스에는 이상적으로 적합하지 않을 수 있습니다. 하지만 해결 방법이 있습니다.
mysqld_safe
해결 방법은 다음 줄을 추가하여 스크립트를 수정하는 것입니다 .
cmd="/usr/bin/numactl --interleave all $cmd"
...즉시~ 후에이 줄...
cmd="$NOHUP_NICENESS"
그 이유는 이 아키텍처를 사용하는 MySQL 서버가 여유 메모리에도 불구하고 과도하게 스왑하는 이유를 설명하기 위해 원래 작성된 훌륭한 기사에서 설명됩니다. 그러나 그것은 저자가 지적한 더 큰 문제의 증상이었습니다.그후"완전히 스와핑 문제는 아니며, 스왑이 비활성화된 경우에도 "메모리 할당 실패"가 포함될 수 있다고 지적했습니다.
http://blog.jcole.us/2010/09/28/mysql-swap-insanity-and-the-numa-architecture/
물론 이것이 귀하의 시스템에 적용되는지 추측하고 있지만 그럴만한 가치가 있는 것 같습니다. 64GB InnoDB 버퍼 풀을 프로비저닝하려고 할 때 새 128GB 시스템에서 문제가 발생했을 때 이 수정 사항을 정확하게 사용했는데 MySQL이 다음이 포함된 시스템에서 여유 공간이 있는 64GB를 찾을 수 없었습니다.아무것도 아님다른 실행 중입니다. 내가 성공적으로 사용할 수 있는 가장 높은 값은 4개의 코어가 포함된 16코어 시스템의 전체 메모리의 1/4 미만이라는 것을 깨달았을 때물리적프로세서 ... 당신이 부딪히는 것 같은 일종의 ... 문제의 본질에 관해 조각을 모을 때였습니다.
답변2
에 대한 문서tmp_table_size이 설정은 임시 테이블의 최대 크기라고 말합니다.메모리 내. 해당 크기를 초과해도 테이블이 가득 차면 오류가 발생하지 않습니다. 이는 메모리의 테이블 사용에서 디스크의 MyISAM 테이블 사용으로의 변경을 트리거합니다.
임시 테이블이 필요한 것보다 더 많은 메모리를 사용하도록 허용했기 때문에 시스템이 충돌하고 있습니다. 메모리 테이블도 마찬가지입니다.
tmp_table_size를 삭제해야 합니다.방법아래에. 이 설정은 전체 최대값이 아니라는 점을 기억하세요. 임시 테이블당 최대값입니다. 엄청나게 큰 임시 테이블(예: 각각 20GB 미만)을 만드는 5개의 쿼리가 있는 경우 이제 최대 100GB의 RAM을 사용하는 임시 테이블이 있습니다. 6번째를 추가하면 서버 전체보다 더 많은 RAM을 사용하게 됩니다.
스크립트가 실제로 MEMORY 스토리지 엔진을 사용하는 경우 변경 사항을 검토한 후 MyISAM 파일에 데이터를 기록하십시오. 대규모 임시 테이블에서 그렇게 빠른 성능이 정말로 필요하다면 더 빠른 스토리지를 확보해야 합니다(예:퓨전아이오,비리덴트외). 그것이 과도하거나 너무 비싸다면 최소한 소비자급 SSD를 고려해 보겠습니다.
MyISAM은 데이터가 시스템 메모리(사용되지 않은 RAM)에 캐시될 때 가장 잘 수행됩니다. 스크립트가 대용량 쿼리(MEMORY 엔진 사용)를 할 때마다 캐시를 날려버리면 MyISAM 성능이 저하될 것입니다.
나는 스크립트가 실제로 성능을 저하시킬 때 성능을 '향상'시키기 위해 MEMORY 스토리지 엔진을 사용하고 있다고 의심합니다. 임시 테이블인 경우 임시 테이블을 사용해야 하며 tmp_table_size는 훨씬 작아야 하며 tmp_table_size가 중단된 후 디스크에 강제로 저장되어야 합니다.
max_heap_table_size 및 tmp_table_size의 기본값은 모두 16MB입니다. 가능하다면 설정을 다시 기본값으로 변경하는 것이 좋습니다. 데이터 세트에 적합한 설정을 찾을 때까지 리소스 사용량(디스크 I/O, 총 메모리 사용량, CPU 사용량 등)을 모니터링하면서 조금씩 위쪽으로 조정하세요.