Commit 95e2558f authored by unknown's avatar unknown

* "transactionality" needs to be preserved by TRUNCATE TABLE:

a table with TRANSACTIONAL=x needs to still have it after TRUNCATE.
No testcase, but without this fix, the frm and the Maria table
got "out of sync" in this case:
create table t1 (a int) row_format=page transactional=0;
truncate table t1;
After TRUNCATE, the Maria table (not the frm) was transactional
(thus logging records, which is wrong).
* fix for non-closed file at end of "maria_chk -r"


sql/table.cc:
  "transactionality" needs to be preserved when truncating.
  It's behind a if() to not cancel the hack added to mysql_truncate()
  today for temporary Maria tables.
storage/maria/ha_maria.cc:
  question for Monty (he also has a big mail from me on the same subject)
storage/maria/ma_check.c:
  question for Monty (likely bugs)
storage/maria/ma_create.c:
  debugging info
storage/maria/ma_open.c:
  fix for datafile left open at end of "maria_chk -r":
  ma_open_datafile() happens after _ma_bitmap_init(), it sets dfile.file
  so needs to set share->bitmap.file.file too (they are copies of
  each other). Otherwise it breaks how closing of files works in
  BLOCK_RECORD (which is that info.dfile.file is not closed
  but share->bitmap.file.file is closed): not setting share->bitmap.file.file
  can lead to forgetting to close a file or closing a wrong file.
parent 83ea6e4f
...@@ -2425,6 +2425,12 @@ void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table) ...@@ -2425,6 +2425,12 @@ void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table)
create_info->row_type= share->row_type; create_info->row_type= share->row_type;
create_info->default_table_charset= share->table_charset; create_info->default_table_charset= share->table_charset;
create_info->table_charset= 0; create_info->table_charset= 0;
/*
See hack in mysql_truncate(); when this is properly fixed, the if() below
can be removed, the assignment can always be made.
*/
if (create_info->transactional == HA_CHOICE_UNDEF)
create_info->transactional= share->transactional;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -2159,6 +2159,17 @@ int ha_maria::create(const char *name, register TABLE *table_arg, ...@@ -2159,6 +2159,17 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
share->avg_row_length); share->avg_row_length);
create_info.data_file_name= ha_create_info->data_file_name; create_info.data_file_name= ha_create_info->data_file_name;
create_info.index_file_name= ha_create_info->index_file_name; create_info.index_file_name= ha_create_info->index_file_name;
#ifdef ASK_MONTY
/*
Where "transactional" in the frm and in the engine can go out of sync.
Don't we want to do, after the setting, this test:
if (!create_info.transactional &&
ha_create_info->transactional == HA_CHOICE_YES)
error;
?
Why fool the user?
*/
#endif
create_info.transactional= (row_type == BLOCK_RECORD && create_info.transactional= (row_type == BLOCK_RECORD &&
ha_create_info->transactional != HA_CHOICE_NO); ha_create_info->transactional != HA_CHOICE_NO);
......
...@@ -2272,6 +2272,20 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info, ...@@ -2272,6 +2272,20 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
llstr(sort_param.start_recpos,llbuff)); llstr(sort_param.start_recpos,llbuff));
if (sort_info.new_info && sort_info.new_info != sort_info.info) if (sort_info.new_info && sort_info.new_info != sort_info.info)
{ {
#ifdef ASK_MONTY
/*
grepping for "dfile.file="
shows several places (ma_check.c, ma_panic.c, ma_extra.c) where we
modify dfile.file without modifying share->bitmap.file.file; those
sound like bugs because the two variables are normally copies of each
other in BLOCK_RECORD (and in other record formats it does not hurt to
change the unused share->bitmap.file.file).
It does matter, because if we close dfile.file, set dfile.file to -1,
but leave bitmap.file.file to its positive value, maria_close() will
close a file which it is not allowed to (maybe even a file in another
engine or mysqld!).
*/
#endif
sort_info.new_info->dfile.file= -1; sort_info.new_info->dfile.file= -1;
maria_close(sort_info.new_info); maria_close(sort_info.new_info);
} }
......
...@@ -289,7 +289,10 @@ int maria_create(const char *name, enum data_file_type datafile_type, ...@@ -289,7 +289,10 @@ int maria_create(const char *name, enum data_file_type datafile_type,
/* Calculate min possible row length for rows-in-block */ /* Calculate min possible row length for rows-in-block */
extra_header_size= MAX_FIXED_HEADER_SIZE; extra_header_size= MAX_FIXED_HEADER_SIZE;
if (ci->transactional) if (ci->transactional)
{
extra_header_size= TRANS_MAX_FIXED_HEADER_SIZE; extra_header_size= TRANS_MAX_FIXED_HEADER_SIZE;
DBUG_PRINT("info",("creating a transactional table"));
}
share.base.min_row_length= (extra_header_size + share.base.null_bytes + share.base.min_row_length= (extra_header_size + share.base.null_bytes +
pack_bytes); pack_bytes);
if (!ci->data_file_length && ci->max_rows) if (!ci->data_file_length && ci->max_rows)
......
...@@ -1335,7 +1335,8 @@ char *_ma_columndef_read(char *ptr, MARIA_COLUMNDEF *columndef) ...@@ -1335,7 +1335,8 @@ char *_ma_columndef_read(char *ptr, MARIA_COLUMNDEF *columndef)
int _ma_open_datafile(MARIA_HA *info, MARIA_SHARE *share, int _ma_open_datafile(MARIA_HA *info, MARIA_SHARE *share,
File file_to_dup __attribute__((unused))) File file_to_dup __attribute__((unused)))
{ {
info->dfile.file= my_open(share->data_file_name, share->mode | O_SHARE, info->dfile.file= share->bitmap.file.file=
my_open(share->data_file_name, share->mode | O_SHARE,
MYF(MY_WME)); MYF(MY_WME));
return info->dfile.file >= 0 ? 0 : 1; return info->dfile.file >= 0 ? 0 : 1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment