Row size too large (8126)

3

It gave me an error loading mysql data.

  Row size too large (> 8126). Changing some columns to TEXT or BLOB or   using ROW_FORMAT = DYNAMIC or ROW_FORMAT = COMPRESSED may help. In current   row format, BLOB prefix of 768 bytes is stored inline.

Does anyone know what kind of error this is?

The same mistake came back to me. But now the solution they gave me does not work. I have several text, date, LongBlob fields.

Occurs after executing this code:

$sqlupdate3 = "Update tb_detalhe_trabalhador SET
   Nome3='$Nome3',Funcao3='$Funcao3',
   MedicaValidade3='$MedicaValidade3',
   MedicaAnexo3='$MedicaAnexo3',
   EPISValidade3='$EPISValidade3',
   ProjectistaNumero3='$ProjectistaNumero3',
   ProjectistaValidade3='$ProjectistaValidade3',
   GasNumero3='$GasNumero3',
   GasValidade3='$GasValidade3',
   RedesNumero3='$RedesNumero3',
   RedesValidade3='$RedesValidade3',
   SoldadorNumero3='$SoldadorNumero3',
   SoldadorValidade3='$SoldadorValidade3',
   MecanicoNumero3='$MecanicoNumero3',
   MecanicoValidade3='$MecanicoValidade3',
   ClasSoldadorNumero3='$ClasSoldadorNumero3', 
   ClasSoldadorValidade3='$ClasSoldadorValidade3'
where id=$id ";

mysql_query($sqlupdate3) or die(mysql_error());

My table has a lot of data. Do you see this update? You have 10 more times this code. Data type text, LongBlob, Date

    
asked by anonymous 09.06.2014 / 18:52

4 answers

9

The existing responses correctly address the problem, but I think that when we talk about exceeding the boundaries of a row in the database, we are dealing with the design of the table itself.

The error basically indicates that the amount of data is too high to fit on a line with your current configuration. Instead of changing all the configuration that besides work will generate performance problems in the future, I suggest redesigning the table (s) to divide the information in a more efficient way.

Example

Your current structure tells me that you are saving all the data in the table "tb_details_worker":

$sqlupdate3 = "
Update tb_detalhe_trabalhador SET
   Nome3 = '$Nome3',
   Funcao3 = '$Funcao3',
   MedicaValidade3 = '$MedicaValidade3',
   MedicaAnexo3 = '$MedicaAnexo3',
   EPISValidade3 = '$EPISValidade3',
   ProjectistaNumero3 = '$ProjectistaNumero3',
   ProjectistaValidade3 = '$ProjectistaValidade3',
   GasNumero3 = '$GasNumero3',
   GasValidade3 = '$GasValidade3',
   RedesNumero3 = '$RedesNumero3',
   RedesValidade3 = '$RedesValidade3',
   SoldadorNumero3 = '$SoldadorNumero3',
   SoldadorValidade3 = '$SoldadorValidade3',
   MecanicoNumero3 = '$MecanicoNumero3',
   MecanicoValidade3 = '$MecanicoValidade3',
   ClasSoldadorNumero3 = '$ClasSoldadorNumero3', 
   ClasSoldadorValidade3 = '$ClasSoldadorValidade3'
where id=$id ";

Data can be organized (grouped) into separate tables, thus contributing to a reduction of data per line:

Tb_worker_table

CREATE TABLE IF NOT EXISTS 'tb_detalhe_trabalhador' (
  'trabalhador_id' int(13) NOT NULL AUTO_INCREMENT COMMENT 'ID do trabalhador',
  'nome' varchar(255) NOT NULL COMMENT 'Nome do trabalhador',
  'funcao' varchar(255) NOT NULL COMMENT 'Função do trabalhador',
  PRIMARY KEY ('trabalhador_id')
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Detalhes dos trabalhadores' AUTO_INCREMENT=1 ;

In this table, only data related to the worker are stored, that is, they relate to each other but do not combine with existing ones.

Table tb_detail_medical_worker

CREATE TABLE IF NOT EXISTS 'tb_detalhe_trabalhador_medica' (
  'id' int(13) NOT NULL AUTO_INCREMENT COMMENT 'Id interno',
  'trabalhador_id' int(13) NOT NULL COMMENT 'O "trabalhador_id" da tabela "tb_detalhe_trabalhador"',
  'validade' date NOT NULL DEFAULT '0000-00-00' COMMENT 'Data de validade',
  'anexo' longblob NOT NULL COMMENT 'Documento',
  PRIMARY KEY ('id')
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Detalhes do trabalhador para médica' AUTO_INCREMENT=1 ;

In this table only the data relating to the worker's medical record are stored.

The relationship between tables is created by the trabalhador_id field.

Note:
The schema indicated is repeated for each group of data you have, that is, you would have a table for the data of Soldador , Redes , etc ...

In this way you do not have problems with the line limits in your table and you have the most "tidy" information.

Data Insertion

Working with more than one table to save the data, you have to insert the data in another way, here is an example:

  • Insert the data in the main table

      
    $sql = "
    INSERT INTO tb_detalhe_trabalhador (nome, funcao) 
    VALUES ($Nome3, $Funcao3)";
    
    mysql_query($sql);
    
    $idTrabalhador = mysql_insert_id(); /* recolher ID que acabou de ser criado para
                                           utilizar ao inserir nas tabelas secundárias
                                           e assim criar a relação entre elas */
    
  • Insert data into child tables

     
    $sql = "
    INSERT INTO tb_detalhe_trabalhador_medica (id, trabalhador_id, 'validade', 'anexo')
    VALUES ($idTrabalhador, $MedicaValidade3, $MedicaAnexo3)";
    
    mysql_query($sql);
    
  • Checks

    For the insert to be controlled, you can check the status of things as mysql_query() is executed:

    /* Preparar Dados
     */
    $sqlTrabalhador = "
    INSERT INTO tb_detalhe_trabalhador (nome, funcao) 
    VALUES ($Nome3, $Funcao3)";
    
    /* Inserir
     */
    if (mysql_query($sqlTrabalhador)) {
    
      // recolhe ID do trabalhador
      $idTrabalhador = mysql_insert_id();
    
      /* Preparar Dados
       */
      $sqlTrabalhadorMedica = "
      INSERT INTO tb_detalhe_trabalhador_medica (id, trabalhador_id, 'validade', 'anexo')
      VALUES ($idTrabalhador, $MedicaValidade3, $MedicaAnexo3)";
    
      if (mysql_query($sqlTrabalhadorMedica)) {
        // restantes inserções para as outras tabelas continuam aqui...
      }
      else {
        echo "Ocorreu um erro ao inserir os dados para Médica";
      }
    }
    else {
      echo "Ocorreu um erro ao inserir os detalhes do trabalhador";
    }
    
        
    26.06.2014 / 23:01
    4

    Reference : link

    Reference 2 : link

    You might want to take a look at this artigo that explains a lot about MySQL line sizes. It is important to note that even if you use TEXT or BLOB fields, the line size may still be smaller than 8K (limit to InnoDB) because it stores the first 768 bytes of each field line in the page .

    The simplest way to fix this is to use formato de arquivo Barracuda . with InnoDB. This basically gets rid of the problem altogether, just storing the 20-byte pointer to the text data instead of storing the sprites 768 bytes.

    1 - Adding next to my.cnf file with [mysqld] section.

    innodb_file_per_table
    innodb_file_format = Barracuda
    

    2 - ALTER in the table to use ROW_FORMAT=COMPRESSED .

    ALTER TABLE nome_tabela
        ENGINE=InnoDB
        ROW_FORMAT=COMPRESSED 
        KEY_BLOCK_SIZE=8;
    
        
    09.06.2014 / 19:03
    4

    The possible answers to your question are quite complex and technical because they vary by the file format InnoDB. Nowadays there are two formats called Antelope and Barracuda .

    The central table file (ibdata1) is always in the Antelope format. . If you use file-per-table mode you can create individual files that can use the Barracuda simply by being innodb_file_format=Barracuda in the my.cnf file:

    [mysqld]
    innodb_file_per_table
    innodb_file_format = Barracuda
    

    The main building blocks for this are:

    • A 16KB page of information stored in InnoDB should contain at least two lines of information. In addition, each page has a header and a footer containing checksums , log sequence numbers, and so on. Here is where you get your one-bit limit less than 8KB per line.

    • Fixed size type data, such as INTEGER, DATE, FLOAT, and CHAR, are stored on this primary data page and added to the size limit.

    • Variable size type data, such as VARCHAR, TEXT, and BLOB, are stored in overload pages, so they do not fully count for the maximum total line limit.

    In the Antelope format up to 768 bytes of each column are stored on the primary data page beyond from being stored on the overload page.

    The Barracuda format supports a format dynamic row , which allows it to store only a 20-byte pointer on the primary data page.

    • Data of variable size types are also prefixed by 1 or more bytes to encode their lengths. And the InnoDB line format also has an array of offsets fields. The inner structure is more or less documented in their wiki .

    The Barracuda format also supports ROW_FORMAT = COMPRESSED to further increase the efficiency for storing information overload.

    My suggestion is for you to check your bank modeling or at least this table because you can hardly exceed the maximum limit of the rows if the table is well modeled. This problem is a strong indication that you are violating the condition of the repeating groups of the First Normal Form.

    A workaround would proceed with changing my.cnf as above and changing the table structure to using ROW_FORMAT = COMPRESSED :

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

    Original Response from Bill Karwin in the Stack Exchange Database Administrators.

    Translation, adaptation and complement: Bruno Augusto (who will it be?)

        
    26.06.2014 / 19:07
    0

    In my case, what I did to solve this problem was to change the table like this:

    Set oRSw = abredb.Execute("ALTER TABLE nome_tabela ENGINE=MyISAM ;")
    Set oRSw = nothing
    
        
    16.01.2016 / 12:56