MySQL 커밋 동안 IO 대기 시간이 너무 길어짐 (99 % IO에서 EXT4 JDB2)


14

python을 사용하여 문서를 인덱싱하고 데이터베이스에 삽입하는 인덱서를 작성 중입니다. 단일 프로세스 이전에 4 개의 병렬 프로세스를 실행하여 다중 처리로 만들었습니다. 모든 텍스트 추출 후 데이터베이스에 삽입하고 커밋을 수행합니다.

이제 IO 문제가 발생했습니다. 주요 IO 문제는 내 프로세스가 아니라 EXT4의 jdb2, 저널링 시스템입니다. 모든 MySQL 커밋에서 IO를 기다리는 것은 99.99 %이며 casuing CPU입니다.

나는 많은 사람들이 인터넷에서 그 문제를 겪는 것을 보았고 그들의 해결책은 barrier = 0을 사용하여 마운트하는 것입니다. 저널링을 완전히 비활성화 하시겠습니까? 내 서버에는 UPS가 있고 그것을 유혹하고 있습니다.


모든 데이터가 InnoDB입니까?
RolandoMySQLDBA

답변:


4

비 저널링 파일 시스템에 데이터베이스를 넣습니다. 최소한 더 큰 서버 (oracle, sql 서버)에는 자체 저널 기능 (트랜잭션 로그)이 있으며 그에 따라 IO를 최적화합니다. 별도의 파일 시스템 및 디스크에 로그 및 데이터베이스가 있으며 잘못된 IO를 처리하기 위해 데이터베이스 내부 기능을 사용합니다. 파일이 확장되지 않기 때문에 쓰기 날짜를 제외하고 일반적으로 (더 큰 설정) 파일 시스템 변경은 없습니다. 파일은 "최종"크기로 생성되며 (관리자가 변경할 수 있음) 변경 내용은 데이터베이스에서 추적 한대로입니다 레벨 트랜잭션 로그.

하드웨어 계층이 무엇인지 알려 주실 수도 있습니다. 대부분의 사람들은 IOPS 가 데이터베이스의 제한 요소 라고 과소 평가 하고 작은 디스크 세트가 큰 데이터베이스에 적합한 환경이라고 생각합니다. 우리 중 일부는 더 많은 수의 디스크를 사용하여 데이터베이스에서 작업하므로 더 많은 수의 IOPS를 지원할 수 있습니다.


데이터에 저널을 사용하지 않고 메타 데이터 만 사용하는 파일 시스템을 사용하도록이를 수정합니다. Ext4도 이런 식으로 구성 할 수 있습니다.
the-wabbit

예. 결국 jouirnal은 IO를 두 배로 늘리고 데이터베이스 로그는 다시 동일한 작업을 수행하므로 필요한 것보다 훨씬 많은 IOPS를 처리해야합니다. 그리고 기본적으로 필요하지 않은 중복성. 시스템 jouirnalling은 파일을 보호하기 위해 좋은 것입니다 ....하지만 응용 프로그램이 이미 그렇게 할 때 쓸모없는 데이터베이스는 없습니다.
TomTom

비 저널링에서 최고의 성능을 제공하는 것은 무엇입니까? 감사!
Phyo Arkar Lwin

4

복원력과 성능 사이에는 항상 상충 관계가 있습니다.

ext4에서 MySQL을 사용하면 barriers = 1 기본값으로 인해 속도가 느려지지만 첫 번째 조치는 저널링을 비활성화하거나 data = writeback을 켜는 것이 아닙니다.

첫째, 복원력이 매우 중요한 경우 배터리 지원 RAID가 그만한 가치가 있습니다.

내가 선택한 배터리 옵션, 특히 비 배터리 백업 RAID에서 선택한 마운트 옵션은 다음과 같습니다.

/dev/mapper/vg-mysql--data  /var/lib/mysql/data ext4  defaults,noatime,nodiratime,barrier=1,data=ordered  0 0

파일 시스템이 손상되어 "크래시 및 저널 복구 후 파일에 오래된 데이터가 man mount표시됨 "(인용)에서 파일 데이터가 손상 될 위험이 없으므로 의도적으로 data = writeback을 사용하지 않습니다 .

I / O 관련 설정에 대한 완벽한 복원력을위한 my.cnf의 이상적인 구성은 다음과 같습니다.

[mysqld]
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1

성능을 높이기 위해 다음과 같은 일련의 절충안을 선택했습니다.

  1. sync_binlog = 0: 이것은 완전한 복원력에서 벗어나는 최초의 MySQL 구성입니다. 그 이유는 특히 binlog_format=row(Jira에게 불행히도 필요한 경우) 성능이 크게 향상 되었기 때문입니다 . binlog가 전원 손실 시나리오에 의해 손상되면 다른 복제본에서 이진 복사를 수행하는 클러스터에서 충분한 MySQL 복제본을 사용하고 있습니다.
  2. innodb_flush_log_at_trx_commit = 2: 완전한 ACID 준수를 위해서는 값 1이 필요하지만 값 2는 "커밋 할 때마다 파일에 로그 버퍼가 기록되지만 디스크로 플러시 작업은 수행되지 않습니다. 로그 파일은 값이 2 일 때도 초당 1 회 발생합니다. 프로세스 스케줄링 문제로 인해 초당 1 회 플러싱이 초당 100 % 보장되는 것은 아닙니다. " (MySQL 문서에서 인용)
  3. 사용할 마운트 옵션을 업데이트하십시오 data=writeback. 이것이 루트 파일 시스템 인 경우 커널 명령 행 옵션도 전달해야합니다. coderwall 에서 몇 가지 단계를 함께 수행했습니다 .
  4. 의 다양한 값을 테스트하십시오 innodb_flush_method. O_DIRECT는 일부 워크로드에서 성능을 향상시키는 것으로 나타 났지만 이것이 사용자 환경에서 작동한다는 것은 아닙니다.
  5. 이 경우 당신은 또한 증가 할 것이다, SSD를 업그레이드 innodb_io_capacity등 및 조정 설정 innodb_adaptive_flushing, innodb_read_io_threads, innodb_write_io_threads, innodb_purge_threads, 기타 가능한 설정.

3

I / O 백엔드가 부하에 잘 대처하지 못할 수 있습니다. 파일 시스템이 데이터를 저널링하지 않는지 확인해야합니다. data=writeback,relatime,nobarrier첫 번째 빠른 및 더티 최적화로 데이터베이스의 데이터 파티션에 마운트하기 위해 매개 변수를 사용하는 것이 좋습니다 .

또한 증상을 유추하면 컨트롤러에서 쓰기 캐싱을 사용하지 않는 것 같습니다. 컨트롤러에서 배터리 지원 또는 플래시 지원 쓰기 캐시를 사용하고 활성화해야합니다.이를 통해 데이터 손실 또는 손상의 위험을 크게 증가시키지 않으면 서 성능을 크게 향상시킬 수 있습니다. 배터리 또는 플래시 백업 없이 쓰기 캐시를 사용 하면 데이터 손실 또는 손상의 위험이 크게 증가 하므로 테스트 목적 및 / 또는 손실을 입을 수있는 경우에만 수행하십시오.


그래서 어떻습니까 : data = writeback, relatime, nobarrier 그리고 mysql Logging을 완전히 비활성화 하시겠습니까? 나는 이것이 일을 많이 가속화 할 것이라고 생각합니까?
Phyo Arkar Lwin

hdpram -i는 쓰기 캐싱을 사용하고 있음을 보여줍니다. 그래서 흠 ??
Phyo Arkar Lwin

@ V3ss0n 트랜잭션 엔진에 대한 로깅을 비활성화 할 수 없습니다. 이것이 바로 핵심입니다. 트랜잭션 로그 는 기본 데이터베이스 데이터 (임의의 읽기 / 쓰기)와 완전히 다른 액세스 패턴 (대개 선형 쓰기)을 갖기 때문에 다른 디스크 세트 로 이동하도록 선택할 수 있습니다. 이것은 일반적으로 권장되는 구성입니다. 스토리지 설정과 관련하여 : RAID 컨트롤러를 사용하지 않고 쓰기 캐시가 설정된 개별 디스크를 사용하고 있습니까? 이는 명시 적 캐시 플러시 요청과 함께 제공되는 동기 쓰기에 도움이되지 않습니다.
the-wabbit

nobarrier은 동일 barrier=0?
Nic Cottrell

@NicCottrell 예, 동일합니다.
kouton

3

이것은 오래된 질문이지만 새로운 전용 서버에서 지난 주에 동일한 문제 (높은 IO 대기 시간 및 끔찍한 삽입 / 업데이트 속도)에 직면 했으며이 솔루션은이 문제를 직접 해결합니다.

tune2fs -O "^has_journal" /dev/<drive>JDB2 프로세스로 인한 IO 대기를 제거하므로 저널링을 사용하지 않는 것이 가장 빠른 솔루션이었습니다. 그러나 충돌시 데이터가 손실되므로 배터리 백업 드라이브가 없으면 권장하지 않습니다. doublewriteMySQL에서 활성화 한 경우 InnoDB 테이블은 안전합니다 . 그러나 .frm, logs 등과 같은 파일은 안전하지 않습니다. 이 파일을 다른 드라이브 (특히 bin 로그)로 이동하려고했지만 jdb2 IO 대기는 계속 유지됩니다. 그래서 우리를 매우 편안하게 두지 않았습니다.

data=writeback,relatime,nobarrier전체 파티션에서 저널링을 비활성화하는 것만 큼 쓰기 / 읽기 속도를 높이는 데 도움이되지 않았습니다. ext4에 대한 추가 옵션은 EXT4 doc에 있습니다.

우리의 경우 실제 범인이었다 sync_binlog. 우리는 같다 설정 한 1에서 /etc/mysql/my.cnf그것은 한 살인 성능을.

Percona는 여기서 이것을 검증합니다 . 우리는 그것을 기본값으로 설정 0하고 성능은 500 % 이상 향상되었습니다.


0

이 데이터를 삽입하기 위해 어떤 데이터베이스 엔진을 사용하고 있습니까?

MyISAM 인 경우 쓰기 중에 전체 테이블을 잠 가야하므로 동시 삽입 스레드를 실행하면 아무리 강력해도 모든 시스템이 종료됩니다.

이 테이블에 InnoDB를 사용하고 있는지 확인하십시오.


트랜잭션을 커밋하고 있기 때문에 MyISAM은 트랜잭션을 지원하지 않기 때문에 엔진은 MyISAM이 아닙니다.
the-wabbit

Arr, brainfart.
어댑터

innodb를 사용하고 있으며 mysql5.5의 기본값은 innodb입니다.
Phyo Arkar Lwin

0

또한 mysql과 직접 관련이 없지만 일부 HD는 적극적인 전원 관리로 인해 ext4에 문제가 있습니다.

비활성화하십시오. 먼저 가지고있는 값을 확인한 다음 (재부팅하지 않고 다시 설정해야하는 경우) 비활성화하십시오.

현재 값을 확인하십시오.

    hdparm -B /dev/sda

비활성화

   hdparm -B 255 /dev/sda

(또는 HD가 무엇이든) 테스트하십시오. 아마도 대부분의 문제에는 도움이되지 않지만 일부 사용자에게는 도움이 될 수 있습니다. 재부팅하면 값이 재설정되거나 이전 값의 255를 수동으로 바꿉니다.

도움이되는 경우 부팅시 설정 하여 /etc/default/hdparm또는 /etc/hdparm.conf보다 영구적 인 구성을 확인하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.