Bug #44230 Altering Falcon table under LOCK TABLES fails with "Can't lock file" error.
Submitted: 13 Apr 2009 7:55 Modified: 26 May 2010 17:52
Reporter: Dmitry Lenev Email Updates:
Status: Unsupported Impact on me:
None 
Category:MySQL Server: Falcon storage engine Severity:S3 (Non-critical)
Version:6.0.11-bzr OS:Linux
Assigned to: Sergey Vojtovich CPU Architecture:Any
Tags: F_HANDLER
Triage: Triaged: D3 (Medium)

[13 Apr 2009 7:55] Dmitry Lenev
Description:
Attempt to ALTER Falcon table under LOCK TABLES fails with "1015: Can't lock file (errno: 178)" error if this table is both write and read locked. The same works fine for MyISAM and InnoDB tables.

How to repeat:
# Script for MySQL's test suite which demonstrates the problem.
-- source include/have_falcon.inc

create table t1 (i int) engine=falcon;
lock tables t1 as a read, t1 write;
# The following statement emits unexpected error.
alter table t1 add column j int;
[13 Apr 2009 9:05] Valeriy Kravchuk
Thank you for the bug report. Verified just as described:

openxs@suse:/home2/openxs/dbs/6.0> bin/mysql -uroot test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 6.0.11-alpha Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> drop table t1;
Query OK, 0 rows affected (0.03 sec)

mysql> create table t1 (i int) engine=falcon;
Query OK, 0 rows affected (0.08 sec)

mysql> lock tables t1 as a read, t1 write;
Query OK, 0 rows affected (0.01 sec)

mysql> alter table t1 add column j int;
ERROR 1015 (HY000): Can't lock file (errno: 178)

Now, let's try with InnoDB:

mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)

mysql> alter table t1 engine=InnoDB;
Query OK, 0 rows affected (0.11 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> lock tables t1 as a read, t1 write;
Query OK, 0 rows affected (0.00 sec)

mysql> alter table t1 add column j int;
ERROR 1060 (42S21): Duplicate column name 'j'

OK, so now we have column added after error in ALTER TABLE? And yes, it works as expected InnoDB:

mysql> alter table t1 add column k int;
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0
[14 Apr 2009 21:55] Kevin Lewis
It looks like The error that is returned from 

alter table t1 add column j int;

is not consistent with what gets done inside Falcon.  
Falcon executes the followingn SQL in StorageDatabase::upgradeTable() successfully;

upgrade table "TEST.T1" ("I" int, "J" int)

The system transaction commits and the table is successfully changed online within Falcon.  Then somewhere within the server an error is reported. This causes an inconsistency between Falcon metadata and the server's.

After Falcon successfully changes the file, the function in sql_table.cc called mysql_fast_or_online_alter_table() returns 0. But for some reason, dispatch_command tries to call trans_rollback_stmt().  The server should not be trying to rollback a DDL that succeeded within a storage engine..
[15 Apr 2009 4:51] Dmitry Lenev
Note that not fixing this would mean that under LOCK TABLES it would be impossible to drop table with new foreign keys without dropping parent table (actually this is the scenario in which this problem was spotted initially).
[23 Apr 2009 23:17] Konstantin Osipov
Dmitri, I can reproduce the bug.
But when I try to drop the table later on I get:

090423 16:16:21 [Note] Event Scheduler: Loaded 0 events
090423 16:16:21 [Note] ./mysqld: ready for connections.
Version: '6.0.11-alpha-valgrind-max-debug-log'  socket: '/opt/local/var/mysql/mysql.sock'  port: 3307  Source distribution
mysqld: sql_base.cc:7695: void tdc_remove_table(THD*, enum_tdc_remove_table_type, const char*, const char*): Assertion `remove_type == TDC_RT_REMOVE_UNUSED || thd->mdl_context.is_exclusive_lock_owner(0, db, table_name)' failed.
[1]    8873 abort (core dumped)  ./mysqld

Looks like a sign of incorrect error handling on our side.
Could you please take a look?