Bug #352 | Slave loses temp tables when it is shutdown/restarted | ||
---|---|---|---|
Submitted: | 30 Apr 2003 14:31 | Modified: | 1 Dec 2008 19:53 |
Reporter: | Guilhem Bichot | Email Updates: | |
Status: | Won't fix | Impact on me: | |
Category: | MySQL Server: Replication | Severity: | S2 (Serious) |
Version: | 4.0, 5.0.67, 5.1 | OS: | Any (all) |
Assigned to: | Mats Kindahl | CPU Architecture: | Any |
[30 Apr 2003 14:31]
Guilhem Bichot
[2 May 2003 7:53]
Guilhem Bichot
This is harder than just changing tmp_file_prefix for slave tables. The hardest is that at restart time the slave tables are not in the table cache anymore, so the slave does not see them, even if they exist on disk. The solution must also work for InnoDB temporary tables and BDB. Let's ask Heikki about temp tables in InnoDB.
[2 May 2003 8:52]
Guilhem Bichot
This bug will probably not be fixed soon. Note that we don't even know the name of the table we discover in tmpdir at slave server restart!! We don't know that this #sql321.frm file corresponds to a former temp table called `mytable`. In the future things will be easier because we will have the CREATE TABLE statement stored in the .frm file. Maybe we should wait until that moment? Then things will be easy for MyISAM: open the #sql.frm file, read the name; re-enter it in the table cache. We will however need the master thread id who originally created this table (maybe we can store it in the temporary file's name). With InnoDB, Heikki has a way to recover a lost temp table in the InnoDB datafile; things will be tougher but possible.
[2 May 2003 13:18]
Guilhem Bichot
Here is a way to get a lost temp table back in InnoDB (if mysqld stops without dropping a temp table, this temp table remains in the InnoDB datafile) : > If you have an orphaned table #sql... inside the tablespace, then by calling > > CREATE TABLE `rsql..._recover_innodb_tmp_table`(...) type = innodb; > > where the table definition is similar to the temporary table, you can make > InnoDB to rename the orphaned table to `rsql..._recover_innodb_tmp_table`. > Then you can dump and drop the renamed table. The backquotes around the > table name are needed because a temporary table name contains the character > '-'. So we need the CREATE TABLE statement for the temp table. Again, this will be solved when we write the CREATE TABLE statement to the frm.
[20 May 2003 13:43]
Guilhem Bichot
Note that this bug is about disk-based tmp tables, not HEAP tables (for which there is no obvious solution). Two problems: 1- the table files must not be deleted at startup 2- at startup, the slave server must have a way to know which thread on which server id created this table. 1- is easy: we can simply create the table in the database directory. Distinguish it from permanent tables using a prefix. 2- we have to make it fast enough in all cases. First include the original server id and thread id in the file name (easy). Then when a slave thread starts, it could scan all databases' directories in search for tmp tables. But which tmp tables is it looking for? Depends on the log event (think of a binlog which was generated by circular replication: it contains events of different server ids). I suggest this: * in init_slave() (some code which is executed only at server startup), scan and collect all tmp tables. Put them in a hash of hash like this: server_id => thread_id => list_of_tables. Also the "server id" keys have a flag "already_used" with them, which is initially 0. * When any slave thread reads an event which is marked LOG_EVENT_THREAD_SPECIFIC_F, look in the hash for this event's server id. If it finds it and its "already_used" is 0, grab the tmp tables for itself, and set "already_used" to 1. This way these tables are its, and only its, because it is responsible for this server id (no other slave thread should have events of this server id, or you have a strange multimaster setup prone to conflicts). In this method we scan the directories only once at startup, which is efficient. Note: some people have 50,000 databases in a server. So we may need an option --skip-slave-scan-for-tmp-tables because the initial scan may take a long time. In that case, users should always be sure that Slave_open_temp_tables == 0 before shutdown. Another different approach: as one day we will need to store info about prepared statements to some file (MyISAM table in the mysql database) so that prepared statements survives a slave shutdown, we could also store info about tmp tables the same way, with columns: database_name table_name server_id thread_id frm_file_name This solution has the advantage of being symmetric of the one for prepared statements.
[27 Aug 2003 4:55]
Guilhem Bichot
For the moment, this is documented in the "Replication Features and Known Problems" section of our manual; as a workaround you have to check that the Slave_open_tables variable is 0 after doing STOP SLAVE and before shutting down the slave.
[16 Oct 2008 6:53]
Sveta Smirnova
Bug still exists in version 5.0.67
[16 Oct 2008 7:03]
Sveta Smirnova
Same error with 5.1 if use statement-based replication. With row-based problem is solved.