mySql-라이브 DB에 대한 innodb_file_per_table 변경


18

나는 큰 MySql DB (150GB)를 가지고 있으며 이제는 innodb_file_per_table로 설정되어 있음을 알았 습니다.off 전체 DB가 하나의 단일 파일 ( ibdata1) 에서 호스팅되도록 . innodb_file_per_tableDB를 여러 파일로 소급 분할하여 활성화 하고 싶습니다. 이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

답변:


32

이것을 풀 수있는 방법은 실제로 하나뿐입니다. mysqldumps를 사용하여 데이터를 내보내고, 모든 데이터베이스를 삭제하고, mysqld를 종료하고, ib_logfile0을 삭제하고, ib_logfile1을 삭제하고, ibdata1을 삭제하고, 제목 innodb_file_per_table아래 에 추가 하고 [mysqld], mysql을 시작해야합니다.

이 답변을 2010 년 10 월에 StackOverflow에 게시했습니다.

다음은 세로로 나열된 단계입니다.

1 단계) MySQL 모든 데이터베이스를 SQL 텍스트 파일로 덤프 (SQLData.sql이라고 함)

2 단계) 모든 데이터베이스 삭제 (mysql 스키마 제외)

단계 03) MySQL 종료

주의 사항 : InnoDB 파일에서 커밋되지 않은 트랜잭션을 완전히 정리하려면 다음을 실행하십시오.

mysql -uroot -p... -Ae"SET GLOBAL innodb_fast_shutdown = 0;"
service mysql stop

단계 04) /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 %인지 확인하십시오.

단계 05) ibdata1, ib_logfile0 및 ib_logfile1 삭제

이 시점에서 / var / lib / mysql에는 mysql 스키마 만 있어야합니다.

단계 06) mysql 재시작

이것은 각각 10G에서 ibdata1, 1G에서 ib_logfile0 및 ib_logfile1을 재생성합니다.

07 단계) SQLData.sql을 mysql로 ​​다시로드

ibdata1은 커지지 만 테이블 메타 데이터 만 포함

각 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로 축소했습니다.

시도 해봐. 이에 대한 추가 질문이 있으면 저에게 이메일을 보내주십시오. 날 믿어. 이것은 단기적으로 그리고 장기적으로 작동합니다. !!!

ibdata1을 축소하지 않고 InnoDB 테이블을 추출하는 대안이 있습니다.

단계 01) /etc/my.cnf에 다음 줄을 추가하십시오

[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G

단계 02) service mysql restart

단계 03) mydb.mytable이라는 단일 InnoDB 테이블을 추출하려면 다음을 수행하십시오.

ALTER TABLE mydb.mytable ENGINE=InnoDB;

이것은 하나의 파일을 생성하여 원래 구조 파일을 유지합니다.

  • /var/lib/mysql/mydb/mytable.frm
  • /var/lib/mysql/mydb/mytable.ibd

모든 InnoDB 테이블에 대해이 작업을 수행 할 수 있습니다. 불행히도 ibdata1은 150GB를 유지합니다.


.sql 파일에서 다시로드를 실행하는 동안 다음과 같은 오류가 발생했습니다 ERROR 1071 (42000) at line 25: Specified key was too long; max key length is 1000 bytes.
Ran

@Ran은 별도의 질문으로 게시하십시오.
RolandoMySQLDBA


모든 단일 테이블에서 설정 innodb_file_per_table한 다음 수행 할 경우 ALTER TABLE, ibdata1 파일을 삭제하여 복원하지 않고 공간을 확보 할 수 있습니까?
SystemParadox

1
@SystemParadox 절대적으로 아닙니다 !!!!!!!! 데이터 사전을 잃게됩니다.
RolandoMySQLDBA

5

ibdata의 공간을 되 찾으려면 Rolando가 지적한 것처럼 덤프 / 복원이 유일한 선택 입니다. 성능이이 작업을 수행하는 것이 가장 좋습니다.

그러나 손실을 줄이고 하드 드라이브에서 150GB를 '손실'하려면 간단히 활성화하십시오. innodb_file_per_table my.cnf에서 하고 서버를 다시 시작 됩니다.

그런 다음 각 테이블에 대해 다음을 발행하십시오.

ALTER TABLE x DISABLE KEYS;
ALTER TABLE x ENGINE=InnoDB;
ALTER TABLE x ENABLE KEYS; 

여기서 문제는 큰 테이블 스페이스가 시간이 걸린다는 것입니다.

내가 제안하는 것은 라이브 DB의 슬레이브를 설정하고 슬레이브에서 변환을 실행 한 다음 마스터 / 슬레이브를 종료하고 새 데이터 공간을 마스터에 복사하거나, 일단 잡히면 슬레이브가 마스터가되도록 승격시키는 것입니다 .

가동 중지 시간없이이 변경을 수행하는 데 어려움이 있습니다.


잔인하게 정직하고 '손실을 줄이십시오'라고 +1했습니다. 당신은 '총알을 물었다'고 말할 수도 있습니다.
RolandoMySQLDBA

pt-online-schema-change를 사용하여 alter 테이블을 실행하는 동안 중단 시간을 피할 수 있습니다.
cornernote
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.