[mysql] “Mysql Row size too large”에 대한 제한 변경

한도를 어떻게 변경할 수 있습니까?

행 크기가 너무 큽니다 (> 8126). 일부 열을 TEXT 또는 BLOB로 변경하거나 사용하면 ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED도움이 될 수 있습니다. 현재 행 형식에서는 BLOB접두사 768 바이트가 인라인으로 저장됩니다.

표:

id  int(11) No
name    text    No
date    date    No
time    time    No
schedule    int(11) No
category    int(11) No
top_a   varchar(255)    No
top_b   varchar(255)    No
top_c   varchar(255)    No
top_d   varchar(255)    No
top_e   varchar(255)    No
top_f   varchar(255)    No
top_g   varchar(255)    No
top_h   varchar(255)    No
top_i   varchar(255)    No
top_j   varchar(255)    No
top_title_a varchar(255)    No
top_title_b varchar(255)    No
top_title_c varchar(255)    No
top_title_d varchar(255)    No
top_title_e varchar(255)    No
top_title_f varchar(255)    No
top_title_g varchar(255)    No
top_title_h varchar(255)    No
top_title_i varchar(255)    No
top_title_j varchar(255)    No
top_desc_a  text    No
top_desc_b  text    No
top_desc_c  text    No
top_desc_d  text    No
top_desc_e  text    No
top_desc_f  text    No
top_desc_g  text    No
top_desc_h  text    No
top_desc_i  text    No
top_desc_j  text    No
status  int(11) No
admin_id    int(11) No 



답변

질문은 serverfault 에서도 요청되었습니다 .

MySQL 행 크기에 대해 많이 설명하는 이 기사 를 살펴볼 수 있습니다 . TEXT 또는 BLOB 필드를 사용하더라도 페이지의 각 필드에 대해 처음 768 바이트를 인라인으로 저장하기 때문에 행 크기가 여전히 8K (InnoDB 제한)를 초과 할 수 있습니다.

이 문제를 해결하는 가장 간단한 방법은
InnoDB 에서 Barracuda 파일 형식 을 사용하는 것 입니다. 이것은 기본적으로 처음 768 바이트를 저장하는 대신 텍스트 데이터에 대한 20 바이트 포인터 만 저장함으로써 문제를 완전히 제거합니다.


OP를 위해 일한 방법은 다음과 같습니다.

  1. 섹션 my.cnf아래 의 파일에 다음을 추가 [mysqld]하십시오.

    innodb_file_per_table=1
    innodb_file_format = Barracuda
  2. ALTER사용할 테이블 ROW_FORMAT=COMPRESSED.

    ALTER TABLE nombre_tabla
        ENGINE=InnoDB
        ROW_FORMAT=COMPRESSED
        KEY_BLOCK_SIZE=8;

위의 방법으로 문제가 해결되지 않을 가능성이 있습니다. InnoDB 엔진 의 알려진 (및 검증 된) 버그 이며 현재 임시 수정 사항은 임시 저장소 로 MyISAM 엔진으로 대체하는 것 입니다. 따라서 파일에서 :my.cnf

internal_tmp_disk_storage_engine=MyISAM


답변

최근에이 문제에 부딪혀 다른 방식으로 해결했습니다. MySQL 버전 5.6.20을 실행중인 경우 시스템에 알려진 버그가 있습니다. MySQL 문서 보기

중요 버그 # 69477로 인해 외부에 저장된 대규모 BLOB 필드에 대한 리두 로그 쓰기가 가장 최근 체크 포인트를 덮어 쓸 수 있습니다. 이 버그를 해결하기 위해 MySQL 5.6.20에 도입 된 패치는 리두 로그 BLOB 쓰기 크기를 리두 로그 파일 크기의 10 %로 제한합니다. 이 제한의 결과로 innodb_log_file_size는 테이블 행에서 발견 된 가장 큰 BLOB 데이터 크기에 다른 가변 길이 필드 (VARCHAR, VARBINARY 및 TEXT 유형 필드)의 길이를 더한 10 배보다 큰 값으로 설정해야합니다.

제 상황에서 문제가되는 blob 테이블은 약 16MB였습니다. 따라서 내가 해결 한 방법은 my.cnf에 해당 금액의 10 배 이상을 확보 한 다음 일부를 추가하는 것입니다.

innodb_log_file_size = 256M


답변

my.cnf 파일에 다음을 설정하고 mysql 서버를 다시 시작합니다.

innodb_strict_mode=0


답변

ENGINE을 전환하고 InnoDB 대신 MyISAM을 사용할 수 있다면 도움이 될 것입니다.

ENGINE=MyISAM

MyISAM에는 두 가지주의 사항이 있습니다.

  1. 거래를 사용할 수 없습니다.
  2. 외래 키 제약 조건을 사용할 수 없습니다.

답변

멋진 답변을 공유하고 싶습니다. 도움이 될 수 있습니다. 크레딧 Bill Karwin은 여기를 참조하십시오 /dba/6598/innodb-create-table-error-row-size-too-large

InnoDB 파일 형식에 따라 다르며 현재 Antelope와 Barracuda라는 두 가지 형식이 있습니다.

중앙 테이블 스페이스 파일 (ibdata1)은 항상 Antelope 형식입니다. 테이블 당 파일을 사용하는 경우 my.cnf에서 innodb_file_format = Barracuda를 설정하여 개별 파일이 Barracuda 형식을 사용하도록 할 수 있습니다.

기본 포인트 :

  1. InnoDB 데이터의 16KB 페이지 하나는 최소한 두 행의 데이터를 보유해야합니다. 또한 각 페이지에는 페이지 체크섬 및 로그 시퀀스 번호 등을 포함하는 머리글과 바닥 글이 있습니다. 여기에서 행당 8KB 미만의 제한을 얻을 수 있습니다.

  2. INTEGER, DATE, FLOAT, CHAR와 같은 고정 크기 데이터 유형은이 기본 데이터 페이지에 저장되며 행 크기 제한에 포함됩니다.

  3. VARCHAR, TEXT, BLOB와 같은 가변 크기 데이터 유형은 오버플로 페이지에 저장되므로 행 크기 제한에 완전히 포함되지 않습니다. Antelope에서는 이러한 열의 최대 768 바이트가 오버플로 페이지에 저장 될뿐만 아니라 기본 데이터 페이지에 저장됩니다. Barracuda는 동적 행 형식을 지원하므로 기본 데이터 페이지에 20 바이트 포인터 만 저장할 수 있습니다.

  4. 가변 크기 데이터 유형에는 길이를 인코딩하기 위해 1 바이트 이상의 접 두부가 붙습니다. InnoDB 행 형식에는 필드 오프셋 배열도 있습니다. 그래서 그들의 위키에 문서화 된 내부 구조가 있습니다.

Barracuda는 또한 ROW_FORMAT = COMPRESSED를 지원하여 오버플로 데이터에 대한 추가 스토리지 효율성을 얻습니다.

또한 잘 디자인 된 테이블이 행 크기 제한을 초과하는 것을 본 적이 없다는 점도 언급해야합니다. First Normal Form의 반복 그룹 조건을 위반하는 것은 강력한 “코드 냄새”입니다.


답변

나는 같은 문제가 있었고 이것이 나를 위해 해결되었습니다.

ALTER TABLE `my_table` ROW_FORMAT=DYNAMIC;

MYSQL 문서에서 :

DYNAMIC 행 형식은 적합한 경우 인덱스 노드에 전체 행을 저장하는 효율성을 유지하지만 (COMPACT 및 REDUNDANT 형식과 마찬가지로)이 새로운 형식은 B- 트리 노드를 많은 수의 데이터 바이트로 채우는 문제를 방지합니다. 긴 열. DYNAMIC 형식은 긴 데이터 값의 일부가 페이지 외부에 저장되는 경우 일반적으로 모든 값을 페이지 외부에 저장하는 것이 가장 효율적이라는 아이디어를 기반으로합니다. DYNAMIC 형식을 사용하면 더 짧은 열이 B- 트리 노드에 남아있어 주어진 행에 필요한 오버플로 페이지 수를 최소화 할 수 있습니다.


답변

몇 시간을 보낸 후 해결책을 찾았습니다. MySQL 관리자에서 다음 SQL을 실행하여 테이블을 MyISAM으로 변환하십시오.

USE db_name;
ALTER TABLE table_name ENGINE=MYISAM;