AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 69656
Accepted
noisebleed
noisebleed
Asked: 2014-07-04 07:00:30 +0800 CST2014-07-04 07:00:30 +0800 CST 2014-07-04 07:00:30 +0800 CST

Não é possível criar a tabela, mas a tabela não existe

  • 772

Estou usando estas etapas para criar uma tabela my_user, que já existia, mas de alguma forma desapareceu do meu banco de dados my_db:

mysql> USE my_db;
mysql> DROP TABLE my_user;
mysql> ERROR 1051 (42S02): Unknown table 'my_user'
mysql> CREATE TABLE my_user (id INT AUTO_INCREMENT NOT NULL, username VARCHAR(255), group_id VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
mysql> ERROR 1005 (HY000): Can't create table 'my_db.my_user' (errno: -1)

Tentei # mysqladmin flush-tablese repeti os passos acima, mas não foi útil. Além disso, reiniciei o mysqlserviço, mas não adianta.

Alguma ideia? O Google falhou comigo até agora. Obrigado.

Informação extra:

mysql> SHOW engine innodb STATUS;
------------------------
LATEST FOREIGN KEY ERROR
------------------------
140703 15:15:09 Error in foreign key constraint of table my_db/my_user
there is no index in the table which would contain
the columns as the first columns, or the data types in the
table do not match the ones in the referenced table
or one of the ON ... SET NULL columns is declared NOT NULL. Constraint:
,
  CONSTRAINT "FK_CFBD431E285FAC6D" FOREIGN KEY ("group_id") REFERENCES "my_group" ("id")
mysql innodb
  • 5 5 respostas
  • 52096 Views

5 respostas

  • Voted
  1. Best Answer
    RolandoMySQLDBA
    2014-07-04T08:34:27+08:002014-07-04T08:34:27+08:00

    Arquitetura InnoDB

    Arquitetura InnoDB

    ANÁLISE

    • De alguma forma, você perdeu os arquivos my_user.frme . my_user.ibdO dicionário de dados ainda tem uma entrada para essa tabela.
    • Você não pode executar DROP TABLE my_user;porque o mysqld procura pelo my_user.frmprimeiro. Como não é my_user.frm, a tabela não pode ser descartada.
    • Embora my_user.frmnão exista, você não pode executar CREATE TABLE my_user ...porque o mysqld pensa que está OK para criar a tabela, mas então adia para o mecanismo de armazenamento. InnoDB diz "Já tenho o tablespace_id de my_user registrado".

    Esta sequência de eventos pode ser comprovada se você criar a tabela usando MyISAM. mysqld irá permitir isso. Uma vez que você muda para o InnoDB, ele volta direto para o dicionário de dados, que está com defeito nessa entrada.

    tenho duas sugestões

    SUGESTÃO #1

    Não crie mais a tabela com esse nome. Usar um nome de tabela diferente

    CREATE TABLE my_usertable (id INT AUTO_INCREMENT NOT NULL, username VARCHAR(255), group_id VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
    

    Isso resultará na alteração do nome da tabela no código do aplicativo

    SUGESTÃO #2

    • mysqldump todos os dados, gatilhos e procedimentos armazenados
    • backup ibdata1
    • excluir ibdata1
    • recarregar o mysqldump
    • Etapas detalhadas da minha postagem do StackOverflow

    Eu lidei com esse problema antes no meu post InnoDB table SELECT retorna ERROR 2006 (HY000): O servidor MySQL foi embora (após queda de energia)

    • 11
  2. Mark C
    2015-01-06T09:11:31+08:002015-01-06T09:11:31+08:00

    Apenas para adicionar minha solução, pois tive um problema semelhante.

    TL;DR

    • Recrie a tabela com a mesma especificação de chave estrangeira, mas com um nome diferente do anteriormente mantido pela tabela.
    • Solte a tabela resultante (também descartará a chave estrangeira órfã original)
    • Recriar tabela com chave original ou sem chave estrangeira

    Detalhe

    Eu me deparei com a situação desagradável em que uma instrução ALTER TABLE falhou devido a uma chave estrangeira não ter sido descartada anteriormente. Isso levou a algumas inconsistências no dicionário de dados do InnoDB (provavelmente devido a http://bugs.mysql.com/bug.php?id=58215 ).

    Pergunta relacionada aqui: https://stackoverflow.com/questions/16857451/error-in-foreign-key-constraint-on-a-droped-table

    mysql> ALTER TABLE `visits` CHANGE COLUMN `variation_visitor_id` `variation_visitor_id` INT(11) NOT NULL  ;
    

    Erro ao renomear de './db/#sql-482c_8448f' para './db/visits' (errno: 150)

    mysql> SHOW ENGINE INNODB STATUS;
    
    Error in foreign key constraint of table db/visits:
     FOREIGN KEY (`variation_visitor_id`) REFERENCES `variations_visitors` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8
    Cannot find an index in the referenced table where the
    referenced columns appear as the first columns, or column types
    in the table and the referenced table do not match for constraint.
    Note that the internal storage type of ENUM and SET changed in
    tables created with >= InnoDB-4.1.12, and such columns in old tables
    cannot be referenced by such columns in new tables.
    See http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html 
    for correct foreign key definitippon.
    

    Como não consegui recuperar a tabela #sql-482c_8448f para visitas, decidi reimportá-la de um backup feito pouco antes da alteração. No entanto, isso falhou. Na investigação:

    • A restrição foi removida de INFORMATION_SCHEMA.TABLE_CONSTRAINTS e INFORMATION_SCHEMA.STATISTICS
    • Mas a restrição ainda estava visível em INFORMATION_SCHEMA.INNODB_SYS_FOREIGN;
    • A tabela não existia, então não pude descartar a chave estrangeira
    • não consegui criar a tabela sem erros

    SQL/Erros

    mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN WHERE ID='db/fk_visits_variations_visitors1';
    
    +-----------------------------------+-----------+------------------------+--------+------+
    | ID                                | FOR_NAME  | REF_NAME               | N_COLS | TYPE |
    +-----------------------------------+-----------+------------------------+--------+------+
    | db/fk_visits_variations_visitors1 | db/visits | db/variations_visitors |      1 |   48 |
    +-----------------------------------+-----------+------------------------+--------+------+
    

    Tentar recriar a tabela sem a chave estrangeira causou um erro 150

    mysql>
    
    SET UNIQUE_CHECKS = 0;
    SET FOREIGN_KEY_CHECKS = 0;
    
    CREATE TABLE `visits` (
      `id` INT(11) NOT NULL AUTO_INCREMENT  ,
      `variation_visitor_id` INT(11) NOT NULL  ,
      PRIMARY KEY (`id`),
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    SET FOREIGN_KEY_CHECKS = 1;
    SET UNIQUE_CHECKS = 1;
    
    ERROR 1005 (HY000) at line 26: Can't create table 'db.visits' (errno: 150)
    
    mysql> SHOW ENGINE INNODB STATUS;
    
    Error in foreign key constraint of table db/visits:
    there is no index in the table which would contain
    the columns as the first columns, or the data types in the
    table do not match the ones in the referenced table
    or one of the ON ... SET NULL columns is declared NOT NULL. Constraint:
    ,
      CONSTRAINT "fk_visits_variations_visitors1" FOREIGN KEY ("variation_visitor_id") REFERENCES "variations_visitors" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION
    

    Tentar criá-lo com causou um erro 121

    mysql>
    
    SET UNIQUE_CHECKS = 0;
    SET FOREIGN_KEY_CHECKS = 0;
    
    CREATE TABLE `visits` (
      `id` INT(11) NOT NULL AUTO_INCREMENT  ,
      `variation_visitor_id` INT(11) NOT NULL  ,
      PRIMARY KEY (`id`),
      KEY `fk_visits_variations_visitors1` (`variation_visitor_id`),
      CONSTRAINT `fk_visits_variations_visitors1` FOREIGN KEY (`variation_visitor_id`) REFERENCES `variations_visitors` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    SET FOREIGN_KEY_CHECKS = 1;
    SET UNIQUE_CHECKS = 1;
    
    ERROR 1005 (HY000) at line 26: Can't create table 'db.visits' (errno: 121)
    
    mysql> SHOW ENGINE INNODB STATUS;
    
    Error in foreign key constraint creation for table `db`.`visits`.
    A foreign key constraint of name `db`.`fk_visits_variations_visitors1`
    already exists. (Note that internally InnoDB adds 'databasename'
    in front of the user-defined constraint name.)
    Note that InnoDB's FOREIGN KEY system tables store
    constraint names as case-insensitive, with the
    MySQL standard latin1_swedish_ci collation. If you
    create tables or databases whose names differ only in
    > the character case, then collisions in constraint
    names can occur. Workaround: name your constraints
    explicitly with unique names.
    

    Eventualmente, usei um novo nome de chave estrangeira. Eu não esperava que isso funcionasse, mas permitiu que a tabela fosse criada.

    mysql>
    
    SET UNIQUE_CHECKS = 0;
    SET FOREIGN_KEY_CHECKS = 0;
    
    CREATE TABLE `visits` (
      `id` INT(11) NOT NULL AUTO_INCREMENT  ,
      `variation_visitor_id` INT(11) NOT NULL  ,
      PRIMARY KEY (`id`),
      KEY `fk_visits_variations_visitors2` (`variation_visitor_id`),
      CONSTRAINT `fk_visits_variations_visitors2` FOREIGN KEY (`variation_visitor_id`) REFERENCES `variations_visitors` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    SET FOREIGN_KEY_CHECKS = 1;
    SET UNIQUE_CHECKS = 1;
    

    Simplesmente descartar a tabela depois removeu o registro errante em INFORMATION_SCHEMA.INNODB_SYS_FOREIGN, permitindo uma importação com o nome da chave estrangeira original.

    • 7
  3. Real Estate Developer
    2014-10-21T06:20:15+08:002014-10-21T06:20:15+08:00

    Existe uma maneira simples de contornar isso, embora seja certo que, em certas circunstâncias, você pode não querer fazer isso. Como esse problema decorre de uma referência interna do InnoDB, você pode simplesmente criar esta tabela com o mesmo nome, mesmas colunas, apenas usando um mecanismo de armazenamento diferente. Encontrei isso em um escravo do MySQL e, embora o mestre do qual eu estava replicando fosse o InnoDB, recriei essa tabela com o MyISAM e consegui voltar a funcionar. Eu escolhi especificamente o InnoDB para meu mecanismo de armazenamento no mestre e, em algumas tabelas, seria importante no escravo também, mas, neste caso, não teve impacto neste escravo para esta tabela, então foi uma maneira rápida para contornar esta questão. Descartar todo o banco de dados teria sido um projeto muito maior.

    • 1
  4. Hevyweb
    2018-06-07T00:18:40+08:002018-06-07T00:18:40+08:00

    Você perdeu os dados da tabela, mas o registro sobre esta tabela ainda existe em "mysql/data/ibdata1". A solução mais fácil é criar esta tabela em algum outro banco de dados e depois copiar os arquivos:

    mysql/data/**dummy_database**/my_user.frm
    
    mysql/data/**dummy_database**/my_user.ibd
    

    para o seu próprio:

    mysql/data/**yours_database**/my_user.frm
    
    mysql/data/**yours_database**/my_user.ibd
    
    • 0
  5. Arthur
    2020-01-15T06:39:16+08:002020-01-15T06:39:16+08:00

    O que funcionou para mim foi:

    • primeiro mova os arquivos .frm e .ibd para outro diretório, por exemplo /tmp/tablebackup *
    • agora extraindo a estrutura da tabela do arquivo .frm usando do ** mysqlfrmdo Oracle mysql-utitilies(porque não tinha outra cópia/backup da estrutura) ex:/usr/bin/mysqlfrm --diagnostic /tmp/tablebackup/MyTable.frm
    • crie uma nova tabela com a estrutura da tabela original, mas com um nome diferente (por exemplo, digamos que a tabela com o problema é MyTableentão criei uma tabela MyTableBcom a estrutura da tabela original)
    • em seguida renomeie a tabela para o nome original de dentro do mysql, por exemplo: RENAME TABLE `MyTableB` TO `MyTable`;(observe que isso só funciona se você não tiver innodb_force_recoverydefinido em seu my.cnf)
    • agora no mysql execute:ALTER TABLE `MyTable` DISCARD TABLESPACE;
    • então copie o .ibdarquivo original (somente o arquivo .ibd, não o arquivo .frm) de volta para o diretório do banco de dados mysql de onde ele foi originalmente movido (não deve haver um arquivo .ibd existente neste momento porque ele é removido pelo DISCARD TABLESPACEcomando)
    • e agora corraALTER TABLE `MyTable` IMPORT TABLESPACE;

    * Reiniciei o mysql após esta etapa, mas não tenho certeza se isso é necessário

    ** mysql-utilities pode requerer instalação mysql-connector-pythonprimeiro

    • 0

relate perguntas

  • Existem ferramentas de benchmarking do MySQL? [fechado]

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

  • Quando é o momento certo para usar o MariaDB em vez do MySQL e por quê?

  • Como um grupo pode rastrear alterações no esquema do banco de dados?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve