테이블에서 데이터 행을 삭제 한 후 MySQL InnoDB가 디스크 공간을 공개하지 않음


140

InnoDB 스토리지 엔진을 사용하는 하나의 MySQL 테이블이 있습니다. 약 2M 개의 데이터 행을 포함합니다. 테이블에서 데이터 행을 삭제해도 할당 된 디스크 공간이 해제되지 않았습니다. optimize table명령 을 실행 한 후 ibdata1 파일의 크기도 줄어들지 않았습니다 .

MySQL에서 디스크 공간을 회수 할 수있는 방법이 있습니까?

나는 나쁜 상황에 처해있다. 이 응용 프로그램은 약 50 개의 다른 위치에서 실행되고 있으며 디스크 공간 부족 문제가 거의 모든 장소에 나타납니다.


optimize 명령을 실행 한 후에도 ibdata1 파일의 크기는 줄어들지 않았습니다.
Sumit Deo

4
나는 그 의견이 더 나은 답으로 편집 한 다음 삭제 될 것이라고 생각
벤 밀우드를

가능한 중복 stackoverflow.com/q/11751792/82114 (그러나 이것은 먼저 여기에 있었다)
FlipMcF

1
"테이블 최적화 명령을 실행 한 후 ibdata1 파일의 크기가 줄어들지 않았습니다." 는 사용자 innodb_file_per_table가 꺼져 있기 때문 입니다. 좋은 소식은이 옵션이 on기본적으로 최신 버전의 MySQL에 있다는 것입니다.
회계사 م

"테이블 xxxx 최적화"를 실행하고 "테이블은 최적화를 지원하지 않습니다. 대신 다시 작성 + 분석"을 수행하십시오. 셸에서 "du -h / var / lib / mysql"을 실행 한 후 데이터베이스가 축소 된 것을 볼 수있었습니다.
user1097111

답변:


137

MySQL은 ibdata1의 크기를 줄이지 않습니다. 이제까지. optimize table삭제 된 레코드에서 사용 된 공간을 비우는 데 사용하더라도 나중에 다시 사용합니다.

다른 방법은 서버를 사용하도록 구성하는 innodb_file_per_table것이지만 백업, 데이터베이스 삭제 및 복원이 필요합니다. 긍정적 인 측면은 테이블의 .ibd 파일이 optimize table.


4
InnoDB 테이블 당 파일 모드 모드 상태에 대한 MySQL 5.5 문서 "기존 테이블의 [InnoDB 파일 당 테이블] 기능을 이용하기 위해 테이블 ​​당 파일 설정을 켜고 기존 테이블에서 실행할 수 있습니다 ALTER TABLE t ENGINE=INNODB. " 이는이 기능을 켜고 기존 테이블을 "변환하여"ALTER TABLE 명령과 함께 별도의 InnoDB 파일을 사용한 다음 테이블을 축소하여 크기를 축소 할 수 있음을 의미합니다. 그러나 일단 완료되면 (거대한) 소스 InnoDB 파일을 삭제하는 방법을 알아야합니다.
Josh

9
나는 이것이 기술적으로 질문에 대답한다고 생각하지만,이 주제를 검색하는 대다수의 사람들이 공간을 축소 / 재생하기 위해 실제 프로세스를 찾고 있다고 생각할 것입니다.이 답변은 제공하지 않습니다.
Manachi

@Manachi 프로세스는 "innodb_file_per_table을 사용하도록 서버 구성", "서버 백업", "데이터베이스 삭제", mysql 중지, ​​.ibd 삭제, 서버 시작 및 데이터베이스 복원입니다. MySQL 5.5 이상에서는 Josh가 말한 것을 사용할 수 있으며 모든 테이블을 변경 한 후 서버를 중지하고 거대한 .ibd를 삭제 한 후 다시 시작할 수 있습니다.
Leonel Martins

39

나 자신도 같은 문제가 있었다.

데이터베이스를 삭제하더라도 innodb는 여전히 디스크 공간을 해제하지 않습니다. 내보내고, mysql을 중지하고, 파일을 수동으로 제거하고, mysql을 시작하고, 데이터베이스와 사용자를 작성한 다음 가져와야했습니다. 200MB의 행만 있었지만 250GB의 innodb 파일을 아끼지 않았다는 점에 감사드립니다.

의도적으로 실패합니다.


10
네, 확실히 실패입니다.
trusktr

1
MySql 5.5에는 동일한 문제가 있습니다. 28GB 테이블의 디스크 사용량을 줄이기 위해 "테이블 최적화"를 실행했습니다. 이 작업은 아마도 원본 복제본을 최적화 된 복제본으로 만들려고 시도했으며, 이렇게하면 파티션의 모든 공간이 소모되었습니다. 이제 "테이블 최적화"에 실패했으며 전체 db를 삭제 한 후에도 파티션에 공간이 없어져 매우 실망했습니다.
basilikode

1
그리고 4 년 이상 후에 나는 MySQL과 같은 문제에 부딪쳤다. MS SQL은 비슷하다 dba.stackexchange.com/questions/47310/...
사바 토스

24

innodb_file_per_table을 사용하지 않으면 디스크 공간을 되 찾을 수 있지만 지루하며 상당한 가동 중지 시간이 필요합니다.

방법은 꽤 깊이있는 -하지만 나는 아래의 관련 부분을 붙여.

덤프에 스키마 사본도 보관하십시오.

현재 시스템 테이블 스페이스에서 데이터 파일을 제거 할 수 없습니다. 시스템 테이블 스페이스 크기를 줄이려면 다음 절차를 수행하십시오.

mysqldump를 사용하여 모든 InnoDB 테이블을 덤프하십시오.

서버를 중지하십시오.

ibdata 및 ib_log 파일을 포함하여 기존 테이블 스페이스 파일을 모두 제거하십시오. 정보의 백업 사본을 유지하려면 MySQL 설치에서 파일을 제거하기 전에 모든 ib * 파일을 다른 위치로 복사하십시오.

InnoDB 테이블의 .frm 파일을 제거하십시오.

새 테이블 스페이스를 구성하십시오.

서버를 다시 시작하십시오.

덤프 파일을 가져옵니다.


단계를 포함하여 주셔서 감사합니다 - '방법'링크가 더 이상이 정보를 포함하지 않는 AFAICT
올란드

3

10 년 후 나는 같은 문제를 겪었다. 나는 다음과 같은 방식으로 해결했다.

  • 남은 모든 데이터베이스를 최적화했습니다.
  • 서비스에서 컴퓨터와 MySQL을 다시 시작했습니다 (Windows + r-> services.msc).

그게 다야 :)


1

공간 회수 문제를 해결하는 다른 방법은 테이블 내에서 여러 파티션 생성-범위 기반, 값 기반 파티션을 사용하여 파티션을 삭제 / 잘라서 공간을 회수하여 특정 파티션에 저장된 전체 데이터가 사용하는 공간을 해제하는 것입니다.

고유 키, 파티션 열을 포함하는 인덱스 등과 같이 테이블 파티셔닝을 도입 할 때 테이블 스키마에 일부 변경이 필요합니다.


0

몇 년 전 mysql5.7 버전에서도 동일한 문제에 직면했으며 ibdata1은 150Gb를 차지했습니다. 그래서 실행 취소 테이블 스페이스를 추가했습니다.

Mysqldump 백업 가져 오기
mysql 서비스 중지
data dir에서 모든 데이터 제거
현재 my.cnf의 undo tablespace 매개 변수 아래에 추가

 #undo tablespace
  innodb_undo_directory =  /var/lib/mysql/
  innodb_rollback_segments = 128 
  innodb_undo_tablespaces = 3
  innodb_undo_logs = 128  
  innodb_max_undo_log_size=1G
  innodb_undo_log_truncate = ON

mysql 서비스
저장소 mysqldump 백업 시작

문제 해결!


-1

MySQL Inodb 엔진의 테이블에서 데이터를 삭제 한 후 디스크 공간을 확보하는 방법에는 여러 가지가 있습니다

처음부터 innodb_file_per_table을 사용하지 않으면 모든 데이터를 덤프하고 모든 파일을 삭제하고 데이터베이스를 다시 작성하고 데이터를 다시 가져 오는 것이 유일한 방법입니다 (위의 FlipMcF 답변 확인)

innodb_file_per_table을 사용하는 경우 시도해 볼 수 있습니다

  1. 모든 데이터를 삭제할 수 있으면 truncate 명령은 데이터를 삭제하고 디스크 공간을 확보합니다.
  2. 테이블 변경 명령은 디스크 공간을 확보 할 수 있도록 테이블을 삭제하고 다시 작성합니다. 따라서 데이터를 삭제 한 후 hardisk를 해제하기 위해 아무것도 변경하지 않는 alter table을 실행하십시오 (예 : table TBL_A에는 charset uf8이 있습니다. 디스크 공간
  3. TBL_A와 같은 TBL_B를 작성하십시오. TBL_A에서 유지하려는 선택 데이터를 TBL_B에 삽입하십시오. TBL_A를 삭제하고 TBL_B의 이름을 TBL_A로 바꾸십시오. 이 방법은 TBL_A와 삭제에 필요한 데이터가 큰 경우에 매우 효과적입니다 (MySQL innodb의 delete 명령은 성능이 매우 떨어짐)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.