2010 년 10 월 StackOverflow 에서이 문제를 해결했습니다. .
InnoDB 인프라에서 가장 바쁜 파일을 명심하십시오 : / var / lib / mysql / ibdata1
이 파일은 일반적으로 네 가지 유형의 정보를 저장합니다
- 테이블 데이터
- 테이블 인덱스
- MVCC (Multiversioning Concurrency Control) 데이터
- 테이블 메타 데이터 (테이블 스페이스 ID 목록)
OPTIMIZE TABLE
ibdata1에 저장된 InnoDB 테이블에 대해 실행 하면 두 가지 작업이 수행됩니다.
- ibdata1 내에서 테이블의 데이터와 인덱스를 연속적으로 만들어서 더 빠르게 액세스
- 연속 데이터 및 색인 페이지가 ibdata1에 추가되므로 ibdata1이 커집니다.
ibdata1에서 테이블 데이터와 테이블 인덱스를 분리하고 innodb_file_per_table을 사용하여 독립적으로 관리 할 수 있지만 전체 디스크 공간 차이는 사라지지 않고 회수 할 수 없습니다. 더해야합니다.
ibdata1을 한 번만 축소 하려면 다음을 수행해야합니다.
1) MySQL 모든 데이터베이스를 SQL 텍스트 파일로 덤프합니다 (/root/SQLData.sql이라고 함).
2) 모든 데이터베이스를 삭제하십시오 (mysql 스키마 제외).
3) MySQL 종료
4) 다음 행을 /etc/my.cnf에 추가하십시오
[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G
참고 : innodb_buffer_pool_size에 대한 설정이 무엇이든, innodb_log_file_size가 innodb_buffer_pool_size의 25 %인지 확인하십시오.
5) ibdata1, ib_logfile0 및 ib_logfile1을 삭제하십시오.
이 시점에서 / var / lib / mysql에는 mysql 스키마 만 있어야합니다.
6) mysql을 다시 시작하십시오
이렇게하면 MySQL 버전에 따라 10MB 또는 18MB의 ibdata1, 1G의 ib_logfile0 및 ib_logfile1이 각각 다시 생성됩니다.
7) /root/SQLData.sql을 mysql로 다시로드
ibdata1은 커지지 만 테이블 메타 데이터 만 포함합니다. 실제로, 그것은 수년에 걸쳐 매우 느리게 성장할 것입니다. ibdata1이 빠르게 성장하는 유일한 방법은 다음 중 하나 이상이있는 경우입니다.
- DDL의 많은 (
CREATE TABLE
, DROP TABLE
, ALTER TABLE
)
- 많은 거래
- 트랜잭션마다 커밋 할 많은 변경 사항
각 InnoDB 테이블은 ibdata1 외부에 존재합니다.
mydb.mytable이라는 InnoDB 테이블이 있다고 가정하십시오. / var / lib / mysql / mydb에 들어가면 테이블을 나타내는 두 개의 파일이 나타납니다.
- mytable.frm (스토리지 엔진 헤더)
- mytable.ibd (mydb.mytable의 테이블 데이터 및 테이블 인덱스 홈)
ibdata1은 더 이상 InnoDB 데이터 및 인덱스를 포함하지 않습니다.
/etc/my.cnf의 innodb_file_per_table 옵션을 사용하면 다음을 실행할 수 있습니다. OPTIMIZE TABLE mydb.mytable;
/var/lib/mysql/mydb/mytable.ibd 파일이 실제로 축소됩니다.
나는 MySQL DBA로 경력에 여러 번이 일을했습니다
사실, 처음이 작업을 수행 할 때 50GB ibdata1 파일을 500MB로 축소했습니다.
시도 해봐. 이에 대한 추가 질문이 있으면 저에게 이메일을 보내십시오. 날 믿어. 이것은 단기적으로 그리고 장거리에서 작동합니다!
업데이트 2012-04-19 09:23 EDT
위 단계를 실행 한 후 조각 모음이 필요한 테이블을 어떻게 확인할 수 있습니까? 알아낼 수는 있지만 스크립트를 작성해야합니다.
예를 들면 다음과 같습니다 mydb.mytable
. 테이블이 있다고 가정합니다 . innodb_file_per_table을 사용하면 /var/lib/mysql/mydb/mytable.ibd 파일이 있습니다.
두 개의 숫자를 검색해야합니다
OS에서 FILESIZE : 다음과 같이 OS에서 파일 크기를 확인할 수 있습니다
ls -l /var/lib/mysql/mydb/mytable.ibd | awk '{print $5}'
INFORMATION_SCHEMA에서 FILESIZE : information_schema.tables에서 다음과 같이 파일 크기를 확인할 수 있습니다.
SELECT (data_length+index_length) tblsize FROM information_schema.tables
WHERE table_schema='mydb' AND table_name='mytable';
OS 값에서 INFORMATION_SCHEMA 값을 빼고 그 차이를 INFORMATION_SCHEMA 값으로 나눕니다.
거기에서 해당 테이블을 조각 모음하는 데 필요한 백분율을 결정합니다. 물론 다음 명령 중 하나를 사용하여 조각 모음을 수행하십시오.
OPTIMIZE TABLE mydb.mytable;
또는
ALTER TABLE mydb.mytable ENGINE=InnoDB;