MySQL은 디스크에 임시 테이블을 만듭니다. 어떻게 중지합니까?


27

현재 사용자가 느리게 찾는 사이트 (무들)를 운영하고 있습니다. 디스크에서 임시 테이블을 만드는 MySQL의 문제를 추적했다고 생각합니다. 나는 변수 시청 created_tmp_disk_tablesMySQL의 워크 벤치 서버 관리 및 약 50 테이블 / s의 수가 증가. 하루 사용 후 created_tmp_disk_tables> 100k입니다. 또한 메모리가 해제되지 않은 것 같습니다. 시스템을 거의 사용할 수 없을 때까지 사용량이 계속 증가하고 MySQL을 다시 시작해야합니다. 거의 매일 다시 시작해야하며 사용 가능한 메모리의 약 30-35 %를 사용하고 하루를 80 %로 마무리합니다.

데이터베이스에 얼룩이없고 쿼리를 제어 할 수 없으므로 최적화 할 수 없습니다. 또한 Percona Confirguration Wizard 를 사용하여 구성 파일을 생성했지만 my.ini도 내 문제를 해결하지 못했습니다.

질문

  1. MySQL이 디스크에 임시 테이블을 생성하지 못하게하려면 무엇을 변경해야합니까? 변경해야 할 설정이 있습니까? 더 많은 메모리를 던져야합니까?

  2. MySQL이 메모리를 차지하지 못하게하려면 어떻게해야합니까?

편집하다

slow_queries로그를 활성화 하고 쿼리 SELECT GET_LOCK()가 느리게 기록 되었음을 발견했습니다 . 빠른 검색 결과 PHP 구성 ( mysqli.allow_persistent = ON) 에서 영구 연결을 허용 한 것으로 나타났습니다 . 나는 이것을 끈다. 이것은 MySQL이 메모리를 소비하는 속도를 줄 였지만 여전히 임시 테이블을 생성하고 있습니다.

나는 또한 key_buffer size충분히 큰지 확인했다 . 나는 변수를 보았다 key_writes. 이것은 0이어야합니다. 그렇지 않은 경우 key_buffer_size.I를 늘리십시오 .0이 key_reads0 key_writes이므로 key_buffer_size충분히 큽니다.

created_tmp_disk_tables가 증가하면 테이블이 메모리에 맞지 않음을 나타낼 수 있으므로 tmp_table_sizeand max-heap-table-size1024M을 늘 렸습니다. 이것은 해결하지 못했습니다.

참조 : http://www.mysqlperformanceblog.com/2007/08/16/how-much-overhead-is-caused-by-on-disk-temporary-tables/

편집 2

sort_merge_passesSHOW GLOBAL STATUS 출력에 초당 많은 수가 표시되면 sort_buffer_size값을 늘리는 것을 고려할 수 있습니다 . 나는 sort_merge_passes한 시간에 2 를 가지고 있었 으므로 sort_buffer_size충분히 크다고 생각합니다 .

참조 : Mysql Manual on sort_buffer_size

편집 3

@RolandoMySQLDBA에서 제안한대로 정렬 및 조인 버퍼를 수정했습니다. 결과는 아래 표에 표시되어 있지만 created_tmp_tables_on_disk여전히 높은 것으로 생각합니다 . 값을 변경 한 후 mysql 서버를 다시 시작하고 created_tmp_tables_on_disk하루 (8h)를 확인하고 평균을 계산했습니다. 다른 제안? 어떤 종류의 컨테이너에는 맞지 않는 것이 있지만 그것이 무엇인지 알아낼 수없는 것 같습니다.

+---------------------+-------------+-------------+--------------------+
| Tmp_table_size,     | Sort_buffer | Join_buffer | No of created      |
| max_heap_table_size |             |             | tmp_tables on disk |
+---------------------+-------------+-------------+--------------------+
| 125M                | 256K        | 256K        |  100k/h            |
+---------------------+-------------+-------------+--------------------+
| 125M                | 512K        | 512K        |  100k/h            |
+---------------------+-------------+-------------+--------------------+
| 125M                | 1M          | 1M          |  100k/h            |
+---------------------+-------------+-------------+--------------------+
| 125M                | 4M          | 4M          |  100k/h            |
+---------------------+-------------+-------------+--------------------+   



이것은 내 구성입니다.

+-----------------------+-----------------------+
|DATABASE SERVER        |WEB SERVER             |
+-----------------------+-----------------------+
|Windows Server 2008 R2 |Windows Server 2008 R2 |
+-----------------------+-----------------------+
|MySQL 5.1.48           |IIS 7.5                |
+-----------------------+-----------------------+
|4 Core CPU             |4 Core CPU             |
+-----------------------+-----------------------+
|4GB RAM                |8GB RAM                |
+-----------------------+-----------------------+

추가 정보

+--------------------+---------+
|PARAM               |VALUE    |
+--------------------+---------+
|Num of tables in Db |361      |
+--------------------+---------+
|Size of database    |2.5G     |
+--------------------+---------+
|Database engine     |InnoDB   |
+--------------------+---------+
|Read/write ratio    |3.5      |
|(Innodb_data_read/  |         |
|innodb_data_written)|         |
+--------------------+---------+
|Avg table size      |15k rows |
+--------------------+---------+
|Max table size      |744k rows|
+--------------------+---------+

이 설정은 나에게 주어 졌으므로 제어가 제한되었습니다. 웹 서버는 CPU와 RAM을 거의 사용하지 않으므로 해당 시스템을 병목 현상으로 제외했습니다. 대부분의 MySQL 설정은 구성 자동 생성 도구에서 시작됩니다.

며칠 동안 PerfMon을 사용하여 시스템을 모니터링했습니다. 이것으로 디스크로 스왑하는 OS가 아니라고 결론을 내립니다.

My.ini

[client]
port=3306
[mysql]
default-character-set=utf8

[mysqld]
port=3306
basedir="C:/Program Files/MySQL/MySQL Server 5.1/"
datadir="D:/DBs/Data/"
default-character-set=utf8
default-storage-engine=INNODB
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
max_connections=125
query_cache_size=350M
table_cache=1520
tmp_table_size=125M
table-definition-cache= 1024
max-heap-table-size= 32M
thread_cache_size=38

MyISAM Specific options
myisam_max_sort_file_size=100G
myisam_sort_buffer_size=125M
key_buffer_size=55M
read_buffer_size=1024K
read_rnd_buffer_size=256K
sort_buffer_size=1024K
join_buffer_size=1024K


INNODB Specific options
innodb_data_home_dir="D:/DBs/"
innodb_additional_mem_pool_size=32M
innodb_flush_log_at_trx_commit=1
innodb_log_buffer_size=16M
innodb_buffer_pool_size=2G
innodb_log_file_size=407M
innodb_thread_concurrency=8

의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
폴 화이트 GoFundMonica 말한다

답변:


16

를 보면 my.ini두 가지 제안이 있습니다.

제안 # 1

나는 당신의 다음 설정을 범프합니다 my.ini

sort_buffer_size=4M
join_buffer_size=4M

이렇게하면 메모리에 조인과 정렬이 유지됩니다. 물론, JOIN이상이 ORDER BY필요 4M하면 MyISAM 테이블로 디스크에 페이징됩니다.

로 로그인 할 수 없으면 root@localhost다음을 사용하여 mysql을 다시 시작하십시오.

C:\> net stop mysql
C:\> net start mysql

root @ localhost로 로그인 할 수 있으면이 설정을 사용하기 위해 mysql을 다시 시작할 필요가 없습니다.

MySQL 클라이언트에서 이것을 실행하십시오.

SET @FourMegs = 1024 * 1024 * 4;
SET GLOBAL sort_buffer_size = @FourMegs;
SET GLOBAL join_buffer_size = @FourMegs;

제안 # 2

데이터가 드라이브에 있으므로 드라이브 D:에 디스크 I / O가있을 수 있습니다 C:.

이 쿼리를 실행하십시오 :

mysql> show variables like 'tmpdir';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| tmpdir        | C:\Windows\TEMP |
+---------------+-----------------+
1 row in set (0.00 sec)

내 데스크탑에서 기본값으로 mysql을 실행하므로 임시 테이블이 Drive에 기록됩니다 C:. D 드라이브는 드라이브보다 더 나은 디스크 인 경우 C:, 아마 당신은 드라이브에 임시 테이블을 매핑 할 수 있습니다 D:설정하여 TMPDIR을 에서 my.ini다음과 같이 :

tmpdir="D:/DBs/"

tmpdir 이 동적 변수가 아니므로 mysql을 다시 시작해야 합니다.

시도 해봐 !!!

업데이트 2013-11-29 10:09 EST

제안 # 3

MySQL이 Windows에서 실행 중이고 핵심 패키지의 쿼리를 만질 수 없다는 사실을 감안할 때 두 가지 아이디어를 함께 수행해야합니다.

IDEA # 1 : 데이터베이스를 Linux 머신으로 이동

당신은 할 수 있어야합니다

  • 리눅스 머신 설정
  • 리눅스 머신에 MySQL 설치
  • Windows에서 MySQL에 대한 이진 로깅 사용
  • 데이터베이스를 텍스트 SQL 파일로 mysqldump
  • Linux에서 실행중인 MySQL에 SQL 파일로드
  • MySQL / Windows에서 MySQL / Linux로 복제 설정

IDEA # 2 : Linux 머신을 가리 키도록 무들을 재구성

무들은 LAMP를 위해 처음 설계되었습니다. localhost 대신 Linux 시스템을 가리 키도록 구성 파일을 변경하십시오.

다음은 MySQL 설정에 관한 오래된 무들 2.3 문서의 링크입니다 : http://docs.moodle.org/23/en/Installing_Moodle#Create_an_empty_database

최신 문서도 사용할 수 있다고 확신합니다.

데이터베이스를 Linux로 옮기는 요점은 무엇입니까 ???

이것이 임시 테이블 상황에 어떻게 도움이됩니까?

그런 다음 임시 테이블의 대상 폴더로 RAM 디스크를 설정하는 것이 좋습니다.

임시 테이블 생성은 여전히 ​​발생하지만 디스크가 아닌 RAM에 기록됩니다. 디스크 I / O를 줄입니다.

업데이트 2013-11-29 11:24 EST

제안 # 4

빠른 RAID-0 디스크 (32 + GB)로 SUGGESTION # 2 를 다시 방문 하여 드라이브 T : (T의 경우 Temp)로 구성하는 것이 좋습니다. 이러한 디스크를 설치 한 후 다음을 추가하십시오 my.ini.

[mysqld]
tmpdir="T:\"

다음을 사용하여 MySQL을 다시 시작해야합니다.

net stop mysql
net start mysql

BTW RAID-1, RAID-10에 비해 우수한 쓰기 성능을 얻을 수 있도록 의도적으로 RAID-0을 말했습니다. tmp 테이블 디스크는 중복으로 만드는 것이 아닙니다.

@RaymondNijland가 언급 한대로 쿼리를 최적화하지 않으면 임시 테이블 생성 횟수를 줄일 수 없습니다. SUGGESTION #3SUGGESTION #4제안은 유일한 대안으로 임시 테이블 생성 및 임시 테이블의 I / O를 가속화.


13

나는 여기에 내 질문에 답한다

@RolandoMySQLDBA를 선호 답변으로 선택합니다. 실제로 문제를 해결하지 못했지만 가장 많은 힌트를 주었기 때문입니다.

아래는 내 조사 결과입니다

결론

Windows의 MySQL은 많은 임시 테이블을 만들고 구성 파일의 내용을 수정하여 MySQL을 조정하면 도움이되지 않습니다.

세부

이 표에는 쿼리를 실행하기 전에 my.ini에서 각각 수정 한 매개 변수가 자세히 설명되어 있습니다. 각 테스트 사이에 MySQL이 다시 시작되었습니다.

원래 질문에서 찾은 my.ini를 템플릿으로 사용한 다음 아래 표에 따라 매개 변수 값을 하나씩 변경했습니다.

JMeter 를 사용 하여 100 번의 동시 웹 요청을 생성했습니다 (사용을 나타냄). Test따라서 각각 1000 개의 요청으로 구성되었습니다. 그 결과 후속 데이터베이스 호출이 발생했습니다. 이것은 MySQL이 변경 한 구성 매개 변수에 관계없이 많은 임시 테이블을 생성한다는 것을 보여주었습니다.

+----+------------+-------+---------------+------------+
|Test|Parameter   |Value  |NumOfTempTables|Db Max Conn |
+----+------------+-------+---------------+------------+
| 1  |key_buffer_ | 25M   | 30682         | 29         |
|    |size        |       |               |            | 
+----+------------+-------+---------------+------------+
| 2  |key_buffer_ | 55M   | 30793         | 29         |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 3  |key_buffer_ | 100M  | 30666         | 28         |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 4  |key_buffer_ | 125M  | 30593         | 24         |
|    |size        |       |               |            | 
+----+------------+-------+---------------+------------+
| 5  |query_cache_| 100M  | 30627         | 32         |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 6  |query_cache_| 250M  | 30761         | 26         |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 7  |query_cache_| 500M  | 30864         | 83*        |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 8  |query_cache_| 1G    | 30706         | 75*        |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 9  |tmp_table_  | 125M  | 30724         | 31         |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 10 |tmp_table_  | 250M  | 30689         | 90*        |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 11 |tmp_table_  | 500M  | 30792         | 28         |
|    |size        |       |               |            |  
+----+------------+-------+---------------+------------+
| 12 |Sort_buffer&| 256K  | 30754         | 28         |
|    |Join_buffer |       |               |            |
+----+------------+-------+---------------+------------+
| 13 |Sort_buffer&| 512K  | 30788         | 30         |
|    |Join_buffer |       |               |            | 
+----+------------+-------+---------------+------------+
| 14 |Sort_buffer&| 1M    | 30788         | 28         |
|    |Join_buffer |       |               |            | 
+----+------------+-------+---------------+------------+
| 15 |Sort_buffer&| 4M    | 30642         | 35         |
|    |Join_buffer |       |               |            |
+----+------------+-------+---------------+------------+
| 16 |innodb-     | 1G    | 30695         | 33         |
|    |buffer-     |       |               |            |
|    |pool-size   |       |               |            |
+----+------------+-------+---------------+------------+
| 17 |innodb-     | 2G    | 30791         | 28         |
|    |buffer-     |       |               |            |
|    |pool-size   |       |               |            | 
+----+------------+-------+---------------+------------+
| 18 |innodb-     | 3G    | 30719         | 34         |
|    |buffer-     |       |               |            |
|    |pool-size   |       |               |            |  
+----+------------+-------+---------------+------------+

* 3 회 평균 실행

아래 이미지는 데이터베이스 서버가 다른 구성에 필요한 메모리 및 CPU 양을 나타냅니다. 검은 색 선은 최소값과 최대 값을 나타내며 파란색 막대는 시작 및 끝값을 나타냅니다. 최대 메모리는 4096M질문에 표시된 것과 같습니다.

메모리 사용량 CPU 사용량


어떤 스토리지 엔진을 사용하고 있습니까? MyISAM 테이블을 사용하지 않는 경우 key_buffer_size에 의존하는 것은 의미가 없습니다. innodb 스토리지 엔진을 사용하는 경우 innodb_buffer_pool_size의 크기는 얼마입니까? query_cache를 사용하고 있습니까?
kasi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.