mysql table already_ERROR 1050 (42S01): Table xxx already exists

在执行ALTER TABLE操作时,MySQL因磁盘空间不足导致服务崩溃,生成了一个孤儿中间表。通过检查错误日志和InnoDB系统表,发现了孤立的#sql-ib379.ibd文件。解决方案包括重命名frm文件匹配ibd文件,然后删除孤儿表,或者通过备份、重建表的方式解决问题。此问题强调了定期检查数据库空间和处理ALTER TABLE操作时确保稳定性的重要性。
摘要由CSDN通过智能技术生成

今天遇到一个关于MySQL求助的问题,修改表结构时遇到“ERROR 1050 (42S01): table xxx already exits"

mysql> ALTER TABLE DAY_BOOK_REPORTADD UNIT_PRICE_PCSDOUBLE(12,2) DEFAULT NULL;

ERROR 1050 (42S01): TABLE 'INVGSP/#SQL-IB379' ALREADY EXISTS

mysql>

检查了后,发现表DAY_BOOK_REPORT确实不存在字段UNIT_PRICE_PCS,但是给表加字段时就报这个错误,遂咨询了一下他具体的操作过程,反馈是当时在做大量数据更新,然后给这个表增加字段时,突然报“DB connect fail”, 登录MySQL服务器检查发现MySQL服务已经挂了,MySQL版本为5.6.20-enterprise-commercial-advanced-log,检查错误日志,发现有下面错误信息:

2018-03-31 23:29:16 7f09c1830700 InnoDB: Error: Write to file ./INVOICE/#sql-ib379.ibd failed at offset 600834048.InnoDB: 1048576 bytes should have been written, only 446464 were written.InnoDB: Operating system error number 0.InnoDB: Check that your OS and file system support files of this size.InnoDB: Check also that the disk is not full or a disk quota exceeded.InnoDB: Error number 0 means 'Success'.InnoDB: Some operating system error numbers are described atInnoDB: http://dev.mysql.com/doc/refman/5.6/en/operating-system-error-codes.html15:29:16 UTC - mysqld got signal 11 ;This could be because you hit a bug. It is also possible that this binaryor one of the libraries it was linked against is corrupt, improperly built,or misconfigured. This error can also be caused by malfunctioning hardware.We will try our best to scrape up some info that will hopefully helpdiagnose the problem, but since we have already crashed,something is definitely wrong and this may fail.key_buffer_size=8388608read_buffer_size=131072max_used_connections=120max_threads=151thread_count=6connection_count=6It is possible that mysqld could use up tokey_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 68245 K  bytes of memoryHope that's ok; if not, decrease some variables in the equation.Thread pointer: 0x9ac95e0Attempting backtrace. You can use the following information to find outwhere mysqld died. If you see no messages after this, something wentterribly wrong...stack_bottom = 7f09c182fe10 thread_stack 0x40000/usr/sbin/mysqld(my_print_stacktrace+0x35)[0x946155]/usr/sbin/mysqld(handle_fatal_signal+0x3d8)[0x6a58c8]/lib64/libpthread.so.0[0x3a6b60f710]/usr/sbin/mysqld[0xa45a2b]/usr/sbin/mysqld[0xa50f5a]/usr/sbin/mysqld[0x9e1afd]/usr/sbin/mysqld[0x9e55a5]/usr/sbin/mysqld[0x96aec5]/usr/sbin/mysqld[0x7790a5]/usr/sbin/mysqld(_Z17mysql_alter_tableP3THDPcS1_P24st_ha_create_informationP10TABLE_LISTP10Alter_infojP8st_orderb+0x1e54)[0x77b204]/usr/sbin/mysqld(_ZN19Sql_cmd_alter_table7executeEP3THD+0x4a5)[0x87fab5]/usr/sbin/mysqld(_Z21mysql_execute_commandP3THD+0x3d4f)[0x72aa4f]/usr/sbin/mysqld(_Z11mysql_parseP3THDPcjP12Parser_state+0x318)[0x72de48]/usr/sbin/mysqld(_Z16dispatch_command19enum_server_commandP3THDPcj+0x11b6)[0x72f7f6]/usr/sbin/mysqld(_Z10do_commandP3THD+0xd7)[0x7310a7]/usr/sbin/mysqld(_Z24do_handle_one_connectionP3THD+0x116)[0x6f8856]/usr/sbin/mysqld(handle_one_connection+0x45)[0x6f8935]/usr/sbin/mysqld(pfs_spawn_thread+0x126)[0xb153e6]/lib64/libpthread.so.0[0x3a6b6079d1]/lib64/libc.so.6(clone+0x6d)[0x3a6b2e89dd]Trying to get some variables.Some pointers may be invalid and cause the dump to abort.Query (7f095e93b2e0): is an invalid pointerConnection ID (thread ID): 4237691Status: NOT_KILLED

从错误提示看,MySQL在往./INVGSP/#sql-ib379.ibd文件写入数据时,遇到了错误,但是最终写入成功(InnoDB: Operating system error number 0.),按错误日志里面的信息提示排查问题:

InnoDB: Check that your OS and file system support files of this size.

InnoDB: Check also that the disk is not full or a disk quota exceeded.

最终检查发现MySQL数据文件所在的分区已经爆了,看错误提示,很有可能是因为空间问题,导致MySQL进程Crash掉了,而MySQL在ALTER TABLE操作过程中崩溃,那么最终可能会在InnoDB表空间中生成一个孤立的中间表(orphaned intermediate table)。 其实#sql-ib379.ibd就是在修改DAY_BOOK_REPORT时,由于MySQL进程Crash掉后生成的孤立中间表。检查如下所示:

mysql> show variables like '%innodb_file_per_table%';+-----------------------+-------+| Variable_name         | Value |+-----------------------+-------+| innodb_file_per_table | ON    |+-----------------------+-------+1 row in set (0.00 sec)mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE '%#sql%';+----------+--------------------+------+--------+-------+-------------+------------+---------------+| TABLE_ID | NAME               | FLAG | N_COLS | SPACE | FILE_FORMAT | ROW_FORMAT | ZIP_PAGE_SIZE |+----------+--------------------+------+--------+-------+-------------+------------+---------------+|      650 | INVOICE/#sql-ib379 |    1 |     65 |   636 | Antelope    | Compact    |             0 |+----------+--------------------+------+--------+-------+-------------+------------+---------------+1 row in set (0.04 sec)mysql>

7524246592ff0f3e4cdd893f866e9180.png

官方文档https://dev.mysql.com/doc/refman/5.6/en/innodb-troubleshooting-datadict.html关于孤立中间表的介绍如下:

Orphan Intermediate Tables

If MySQL exits in the middle of an in-placeALTER TABLEoperation (ALGORITHM=INPLACE), you may be left with an orphan intermediate table that takes up space on your system. This section describes how to identify and remove orphan intermediate tables.

Intermediate table names begin with an #sql-ib prefix (e.g., #sql-ib87-856498050). The accompanying .frm file has an #sql-* prefix and is named differently (e.g., #sql-36ab_2.frm).

To identify orphan intermediate tables on your system, you can viewTable Monitoroutput or queryINFORMATION_SCHEMA.INNODB_SYS_TABLES. Look for table names that begin with #sql. If the original table resides in afile-per-tabletablespace, the tablespace file (the #sql-*.ibd file) for the orphan intermediate table should be visible in the database directory.

找到对应的frm文件(这里是#sql-71a_40a97b.frm),然后将其命名为#sql-ib379.frm(数据文件为#sql-ib379.ibd), 然后删除表(对应的文件会删除)即可解决上面这个问题。

# mv "#sql-71a_40a97b.frm" "#sql-ib379.frm"

mysql>DROP TABLE `#mysql50##sql-ib379`

-> ;

Query OK, 0 rows affected (0.11 sec)

mysql>SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE '%#sql%';

Empty set (0.01 sec)

mysql>

个人还测试了网上另外一种方法,就是首先先删除#sql开头的这些文件,然后拷贝源表数据到备份表,接着删除原表,最后将备份表重命名为源表。添加相关索引。这种方法也能解决这个问题。

mysql> show index from DAY_BOOK_REPORT;mysql> create table DAY_BOOK_REPORT_BK as select * from DAY_BOOK_REPORT;mysql> drop table DAY_BOOK_REPORT;mysql> rename table DAY_BOOK_REPORT_BK to DAY_BOOK_REPORT;mysql>ALTER TABLE DAY_BOOK_REPORT ADD INDEX INDEX_NAME (column_list) --根据实际情况输入具体字段mysql>ALTER TABLE DAY_BOOK_REPORT ADD UNIQUE (column_list) --根据实际情况输入具体字段mysql>ALTER TABLE DAY_BOOK_REPORT ADD PRIMARY KEY (column_list) --根据实际情况输入具体字段

参考资料:

https://dev.mysql.com/doc/refman/5.6/en/innodb-troubleshooting-datadict.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个错误意味着在创建表时,已经存在一个名为'users'的表。可能是之前已经创建过了,或者是在创建表时出现了错误导致表没有被正确删除。需要检查数据库中是否已经存在该表,如果存在则可以尝试删除该表或者修改表名。 ### 回答2: 错误指出表“users”已经存在,通常这个错误表示在尝试创建一个新的表时出现了问题。当数据库管理系统(DBMS)执行SQL语句时,如果该表在数据库中已经存在,则会发生此类错误。这种情况可能发生在以下情况: 1. 重新安装或升级数据库管理系统。在升级后,已经创建的表可能会随着新版本的安装而再次创建,导致表已经存在。 2. 在数据库中手动创建表。如果已经手动创建了表,则无需尝试再次创建,否则系统将返回“表已经存在”的错误。 3. 恢复备份数据。在恢复备份的数据时,已经存在的表将被替换,这可能会导致表已经存在的错误。 如果出现表已经存在的错误,您需要执行以下几个步骤: 1. 检查‘users’表已经存在。使用DESC命令获取表的详细信息:DESC users; 2. 如果表已经存在,删除该表:DROP TABLE users; 3. 创建一个新的表,并添加所需的列:CREATE TABLE users (id INT PRIMARY KEY, username VARCHAR(50), password VARCHAR(50), email VARCHAR(100), role ENUM('user', 'admin')); 4. 您还可以选择在创建表之前备份表数据,以便在表已经存在时可以恢复数据。 总之,当您遇到“表已经存在”的错误时,需要先检查表是否已经存在,然后删除该表并重新创建一个新的表。记得在处理数据库时,要格外小心谨慎,避免重复或错误的操作导致数据丢失或错误。 ### 回答3: 在MySQL数据库中,当我们在创建一个新的表的时候,如果该表在数据库中已经存在,那么就会出现错误 1050 (42s01) at line 1: table 'users' already exists。 这个错误的原因是因为MySQL不允许在同一数据库中存在同名的表。当我们尝试创建同名的表时,就会报出上述的错误。 解决这个问题的方法有以下两种: 1. 删除已存在的表 我们可以使用DROP TABLE语句删除已存在的表,然后重新创建同名的表。下面是示例代码: DROP TABLE IF EXISTS users; CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50), email VARCHAR(50) ); 首先我们使用DROP TABLE IF EXISTS语句删除名为users的表,然后使用CREATE TABLE语句重新创建同名的表。 2. 修改表名 如果我们不想删除表,我们也可以通过修改表名来解决这个问题。我们可以将已存在的表名修改成一个新的名字,然后重新使用原来的表名创建一个新的表。下面是示例代码: RENAME TABLE users TO users_backup; CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50), email VARCHAR(50) ); 首先我们使用RENAME TABLE语句将名为users的表修改成users_backup,然后使用同名的CREATE TABLE语句创建一个新的users表。 总结: 在MySQL数据库中,如果我们尝试在同一数据库中创建同名的表,就会出现错误 1050 (42s01) at line 1: table 'users' already exists。我们可以通过删除已存在的表或者修改表名的方式来解决这个问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值