성능을 얻기 위해 여러 측면에서 MYSQL을 최적화하는 방법을 도입했습니다. 최적화는 궁극적으로 전체 시스템에 대한 이해가 필요하기 때문에 복잡한 작업입니다. 시스템/애플리케이션에 대한 지식이 거의 없이 일부 로컬 최적화를 수행하는 것도 가능하지만 시스템을 더욱 최적화하고 싶을수록 알아야 합니다. 따라서 이 장에서는 MySQL을 최적화하는 다양한 방법에 대한 몇 가지 예를 설명하고 제공할 것입니다. 하지만 시스템에 더 빠른 방법이 항상 남아 있다는 점을 기억하십시오. 시스템 속도를 높이는 데 있어 가장 중요한 부분은 물론 기본 설계입니다. 또한 시스템이 이와 같은 작업을 수행한다는 점을 알아야 하며, 이것이 가장 일반적인 병목 현상입니다.
디스크 검색. 디스크가 데이터 조각을 찾는 데 걸리는 시간입니다. 1999년에 사용된 최신 디스크의 평균 시간은 일반적으로 10ms 미만이므로 이론적으로는 초당 약 1000회 검색할 수 있습니다. 하나의 테이블을 최적화하는 방법은 디스크가 데이터를 읽어야 하는 올바른 위치에 있을 때 데이터를 여러 디스크에 분산시키는 것입니다. 하나의 디스크 전송은 10-20Mb/s와 같습니다. 병렬 CPU 주기로 여러 디스크에서 읽을 수 있으므로 최적화하기가 더 쉬워야 합니다. 데이터를 메모리로 읽을 때(또는 이미 있는 경우) 이를 처리해야 합니다. 이는 상대적으로 작은 메모리를 가진 테이블의 경우 가장 일반적인 제한 요소이지만 작은 테이블의 경우 메모리 대역폭은 일반적으로 CPU가 감당할 수 있는 것보다 더 많은 데이터를 필요로 할 때 메모리 병목 현상이 발생합니다. 이는 대부분의 시스템에서 흔히 발생하는 병목 현상이지만 이를 알고 있어야 합니다. 10.2 시스템/컴파일 시간 및 부팅 매개변수 조정 이러한 결정 중 일부는 매우 일찍 이루어지기 때문에 시스템 수준부터 시작합니다. 다른 경우에는 큰 이득을 얻는 데 중요하지 않기 때문에 이 섹션을 잠깐 살펴보는 것만으로도 충분할 수 있지만, 이 수준에서 이득이 얼마나 큰지 느끼는 것이 항상 좋습니다. 다중 CPU를 어느 정도 사용하려면 Solaris(스레드가 정말 잘 작동하기 때문에) 또는 Linux(2.2 코어의 SMP 지원이 정말 좋기 때문에)를 사용해야 합니다. 그리고 32비트 시스템에서는 Linux의 기본 파일 크기 제한이 2G입니다. 새로운 파일 시스템(XFS)이 출시되면 이 문제가 곧 수정되기를 바랍니다. 우리는 많은 플랫폼에서 프로덕션 MySQL을 실행하지 않기 때문에 잠재적으로 선택하기 전에 실행하려는 플랫폼을 테스트하는 것이 좋습니다.
기타 제안 사항:
RAM이 충분하면 모든 스왑 장치를 제거할 수 있습니다. 일부 운영 체제에서는 여유 메모리가 있더라도 SWAP 장치를 사용합니다. 외부 잠금을 방지하려면 --skip -locking MySQL 옵션을 사용하세요. MySQL 기능은 하나의 서버에서만 실행됩니다. myisamchk를 실행하기 전에 서버를 중지(또는 관련 부분을 잠그는 것)하는 것을 기억하십시오. 일부 시스템에서는 모든 경우에 외부 잠금을 사용할 수 없기 때문에 이 스위치가 필수입니다. MIT-pthreads로 컴파일할 때 --skip-locking 옵션은 기본적으로 on(on)으로 설정됩니다. 왜냐하면 모든 플랫폼에서 Flock()이 MIT-pthreads에서 완벽하게 지원되지 않기 때문입니다. 유일한 경우는 MySQL 서버를 실행할 때입니다. 클라이언트) 동일한 데이터에 대해 --skip-locking을 사용할 수 없습니다. 그렇지 않으면 먼저 mysqld 서버를 플러시하거나 잠그지 않고 테이블에서 myisamchk를 실행할 수 있습니다. --skip을 사용하는 경우에도 LOCK TABLES/UNLOCK TABLES를 계속 사용할 수 있습니다. -잠금.
컴파일과 링크가 MySQL 속도에 미치는 영향
다음 테스트의 대부분은 Linux에서 MySQL 벤치마크를 사용하여 수행되었지만 다른 운영 체제 및 워크로드에 대한 몇 가지 정보를 제공해야 합니다. -static으로 연결하면 가장 빠른 실행 파일을 얻을 수 있습니다. TCP 대신 데이터베이스에 연결 /IP는 또한 더 나은 성능을 제공할 수 있습니다. Linux에서는 pgcc 및 -O6으로 컴파일할 때 가장 빠른 코드를 얻을 수 있습니다. 이러한 옵션으로 "sql_yacc.cc"를 컴파일하려면 gcc/pgcc에 많은 양의 메모리가 필요합니다. MySQL을 구성할 때 libstdc++ 라이브러리를 포함하지 않도록 CXX=gcc도 설정해야 합니다(필요하지 않음). 더 나은 컴파일러나 더 나은 컴파일러 옵션을 사용하면 10을 얻을 수 있습니다. -30% 애플리케이션 속도 향상. 이는 SQL 서버를 직접 컴파일하는 경우 특히 중요합니다. 예를 들어, pgcc 또는 Cygnus CodeFusion 컴파일러를 사용해야 합니다. 새로운 Fujitsu 컴파일러를 테스트했지만 아직은 아닙니다. MySQL 컴파일을 최적화할 수 있을 만큼 오류가 없습니다.
우리가 만든 측정 시트는 다음과 같습니다.
-O6과 함께 pgcc를 사용하고 무엇이든 컴파일하면 mysqld 서버는 gcc(문자열 99 버전 사용)보다 11% 더 빠릅니다. (-static 없이) 동적으로 링크하면 결과가 13% 더 느려집니다. 여전히 동적으로 연결된 MySQL 라이브러리를 사용할 수 있습니다. Unix 소켓 대신 TCP/IP를 사용하는 경우 결과는 Sun Pro C++보다 7.5% 더 빠릅니다. 4.2는 13% 더 빠릅니다. Solaris 2.5.1에서 MIT-pthreads는 단일 프로세서의 기본 스레드를 사용하는 경우보다 8-12% 더 느립니다. TcX 제공: Linux 배포판은 pgcc로 컴파일되고 정적으로 링크됩니다.
앞서 언급한 것처럼 디스크 검색은 큰 성능 병목 현상을 발생시킵니다. 데이터가 증가하기 시작하여 캐싱이 불가능해지면 이 문제는 점점 더 분명해집니다. 읽기에는 최소한 하나의 디스크 탐색이 필요하고 쓰기에는 여러 디스크 탐색이 필요하다는 점을 고려하십시오. 이 문제를 최소화하려면 사용 가능한 디스크 스핀들 수를 늘리고 탐색 오버헤드를 줄이려면 디스크를 사용하십시오. 파일을 다른 디스크에 심볼릭 링크하거나 디스크를 분할하는 것이 가능합니다. 심볼릭 링크를 사용하면 일반 데이터 디렉터리의 인덱스/데이터 파일을 다른 디스크에 기호적으로 링크할 수 있습니다(분할 수도 있음). (디스크가 다른 용도로 사용되지 않는 경우) 10.2.2.1 데이터베이스 및 테이블에 심볼릭 링크 사용을 참조하십시오. 분할 분할은 많은 디스크가 있고 첫 번째 블록이 한 디스크에 있고 두 번째 블록이 두 번째 디스크에 있음을 의미합니다. , n번째 블록은 (n mod number_of_disks)번째 디스크에 있습니다. 이는 일반 데이터 크기가 분할 크기보다 작은 경우(또는 완벽하게(따라서 정렬된 경우)) 약간 더 나은 성능을 얻을 수 있음을 의미합니다. 분할 크기는 OS 및 분할 크기에 따라 크게 달라집니다. 따라서 10.8 자체 벤치마크 사용을 참조하세요. 분할은 분할 방법에 따라 매개변수에 따라 크게 달라집니다. 매개변수와 디스크 수에 따라 차수 차이를 얻을 수 있습니다. 안정성을 위해 RAID 0+ 1(분할 + 미러)을 사용할 수도 있지만 최적화를 선택해야 합니다. 이 경우 N개 드라이브의 데이터를 보관하려면 2*N개 드라이브가 필요합니다. 돈이 있다면 이것이 최선의 선택일 것입니다. 그러나 이를 효율적으로 처리하려면 볼륨 관리 소프트웨어에 투자해야 할 수도 있습니다. 좋은 옵션은 덜 중요한 데이터(재생 가능)를 RAID 0 디스크에 두고, 매우 중요한 데이터(예: 호스트 정보 및 로그 파일)를 RAID 0+ 1 또는 RAID N 디스크에 두는 것입니다. 패리티 비트 업데이트로 인해 RAID N이 문제가 될 수 있습니다. 데이터베이스에서 사용하는 파일 시스템에 대한 매개변수를 설정할 수도 있습니다. noatime 옵션을 사용하여 파일 시스템을 마운트하는 것이 좋습니다. 업데이트를 건너뛰는 inode를 사용하면 일부 디스크 검색을 피할 수 있습니다.
데이터베이스 디렉터리에서 다른 위치로 테이블과 데이터베이스를 이동하고 이를 새 위치에 연결하는 기호로 바꿀 수 있습니다. 예를 들어, 여유 공간이 더 많은 파일 시스템으로 데이터베이스를 이동할 수 있습니다. MySQL 주의 사항 테이블은 기호 링크를 확인하고 실제로 가리키는 테이블을 사용하는 기호 링크입니다. 이는 realpath() 호출을 지원하는 모든 시스템에서 작동합니다(적어도 Linux 및 Solaris는 realpath()를 지원합니다)! realpath()를 지원하지 않는 시스템에서는 실제 경로와 심볼릭 링크를 통해 동시에 테이블에 액세스하면 안 됩니다. 그렇게 하면 MySQL은 데이터베이스 링크를 지원하지 않습니다. 기본적으로 데이터베이스 간에 심볼릭 링크를 만들지 않는 한 모든 것이 잘 작동합니다. MySQL 데이터 디렉터리에 데이터베이스 db1이 있고 db1을 가리키는 심볼릭 링크 db2를 만든다고 가정합니다.
쉘&> cd /path/to/datadir
쉘&> ln -s db1 db2
이제 db1의 모든 테이블 tbl_a에 대해 db2의 테이블 tbl_a도 있을 것입니다. 한 스레드가 db1.tbl_a를 업데이트하고 다른 스레드가 db2.tbl_a를 업데이트하면 문제가 발생합니다. "mysys/mf_format.c"를 변경해야 합니다:
if (!lstat(to,&stat_buff)) /* 심볼릭 링크인지 확인 */
if (S_ISLNK(stat_buff.st_mode) && 실제 경로(to,buff))
코드를 다음과 같이 변경하세요.
if (실제 경로(to,buff))