mariadb/mysys/my_symlink2.c
unknown d6f2fda680 Fixed REPAIR/CHECK/ANALYZE TABLE for tables with new BLOCK-ROW format.
Fixed maria_chk to repair BLOCK-ROW tables.
Added CREATE options ROW_FORMAT=PAGE & TRANSACTIONAL= 0|1
More DBUG information in a lot of functions
Some minor code cleanups
Enable handler errors earlier for better clear text error messages at handler startup / standalone usage.
Don't print NULL strings in my_create_with_symlink();  Fixes core dump when used with --debug


include/maria.h:
  Added extra variables needed for REPAIR with BLOCK records
include/my_base.h:
  Added argument for opening copy of maria table without a shared object
include/my_handler.h:
  Prototypes for my_handler_error_register() & my_handler_error_unregister()
include/pagecache.h:
  Added PAGECACHE_READ_UNKNOWN_PAGE
mysql-test/include/ps_conv.inc:
  Enforce creation of table as MyISAM (to allow one to use --default-storage-engine)
mysql-test/r/maria.result:
  Moved some things to maria-connect.test
  Updared results as REPAIR now works
  Added tests for creation option TRANSACTIONAL
mysql-test/r/ps_2myisam.result:
  Enforce creation of table as MyISAM (to allow one to use --default-storage-engine)
mysql-test/r/ps_3innodb.result:
  Enforce creation of table as MyISAM (to allow one to use --default-storage-engine)
mysql-test/r/ps_4heap.result:
  Enforce creation of table as MyISAM (to allow one to use --default-storage-engine)
mysql-test/r/ps_5merge.result:
  Enforce creation of table as MyISAM (to allow one to use --default-storage-engine)
mysql-test/r/ps_7ndb.result:
  Enforce creation of table as MyISAM (to allow one to use --default-storage-engine)
mysql-test/r/ps_maria.result:
  Enforce creation of table as MyISAM (to allow one to use --default-storage-engine)
mysql-test/t/maria.test:
  Moved some things to maria-connect.test
  Updared results as REPAIR now works
  Added tests for creation option TRANSACTIONAL
mysys/mf_iocache.c:
  More debugging
mysys/mf_tempfile.c:
  Added missing close()
mysys/my_error.c:
  init_glob_errs() is now done in my_init()
mysys/my_handler.c:
  Added functions to initialize handler error messages
mysys/my_init.c:
  Moevd init_glob_errs() here.
mysys/my_open.c:
  More comments
  More debugging
  Code cleanup (join multiple code paths) and indentation fixes. No change in logic.
mysys/my_symlink2.c:
  Don't print NULL strings
sql/handler.cc:
  Added printing of PAGE row type
  Moved out initializing of handler errors to allow handler to give better error messages at startup
sql/handler.h:
  ROW_TYPE_PAGES -> ROW_TYPE_PAGE
sql/lex.h:
  Added 'PAGE' and 'TRANSACTIONAL'
sql/mysqld.cc:
  Initialize handler error messages early to get better error messages from handler startup
sql/sql_show.cc:
  ROW_TYPE_PAGES -> ROW_TYPE_PAGE
sql/sql_table.cc:
  Removed not needed initializer
sql/sql_yacc.yy:
  Added CREATE options ROW_FORMAT=PAGE and TRANSACTIONAL=[0|1]
sql/table.cc:
  Store transactional flag in .frm
  More comments
sql-bench/example:
  Better example
sql/table.h:
  Added transactional table option
storage/maria/ha_maria.cc:
  More debug information
  Enable REPAIR
  Detect usage of TRANSACTIONAL table option
storage/maria/ma_bitmap.c:
  More comments (from Guilhem)
storage/maria/ma_blockrec.c:
  SANITY_CHECK -> SANITY_CHECKS (fixed typo)
  Write out pages on delete even if there is no rows. (Fixed problem with REPAIR)
  Removed some ASSERTS to runtime checks (for better REPAIR)
  Fixed bug when scanning rows
  More DBUG information
storage/maria/ma_check.c:
  Partial rewrite to allow REPAIR of BLOCK/PAGE format.
  Repair of BLOCK format rows is for now only done with 'maria_repair()' (= repair through key cache)
  The new logic to repair rows with BLOCK format is:
  
  - Create new, unrelated MARIA_HA of the table
  - Create new datafile and associate it with new handler
  - Reset all statistic information in new handler
  - Copy all data to new handler with normal write operations
  - Move state of new handler to old handler
  - Close new handler
  - Close data file in old handler
  - Rename old data file to new data file.
  - Reopen data file in old handler
storage/maria/ma_close.c:
  REmoved not needed block
storage/maria/ma_create.c:
  Swap arguments to _ma_initialize_data_file()
storage/maria/ma_delete_all.c:
  Split maria_delete_all_rows() to two functions to allow REPAIR to easily reset all status information.
storage/maria/ma_dynrec.c:
  Added checksum argument to _ma_rec_check (multi-thread fix)
storage/maria/ma_info.c:
  Indentation fix
storage/maria/ma_init.c:
  Register error message to get better error message on init and when using as standalone module.
storage/maria/ma_loghandler.c:
  Fixed typo that disabled some error detection by valgrind
storage/maria/ma_open.c:
  Added 'calc_check_checksum()'
  Don't log things during repair
  Added option HA_OPEN_COPY to allow one to open a Maria table with an independent share (required by REPAIR)
storage/maria/ma_pagecache.c:
  Fixed some compiler warnings
  Added support for PAGECACHE_READ_UNKNOWN_PAGE (used for scanning file without knowing page types)
storage/maria/ma_test_all.sh:
  More test of REPAIR
storage/maria/ma_update.c:
  Optimized checksum code
storage/maria/maria_chk.c:
  Use DBUG_SET_INITIAL() to get DBUG to work with --parallel-repair
  Ensure we always use maria_repair() for BLOCK format (for now)
  More DBUG information
storage/maria/maria_def.h:
  For now, always run with more checkings (SANITY_CHECKS)
  Added share->calc_check_checksum to be used with REPAIR / CHECK table.
  Swaped arguments to _ma_initialize_data_file()
storage/myisam/ft_stopwords.c:
  Added DBUG information
mysql-test/r/maria-connect.result:
  New BitKeeper file ``mysql-test/r/maria-connect.result''
mysql-test/t/maria-connect.test:
  New BitKeeper file ``mysql-test/t/maria-connect.test''
2007-07-01 16:20:57 +03:00

172 lines
4.7 KiB
C

/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Advanced symlink handling.
This is used in MyISAM to let users symlinks tables to different disk.
The main idea with these functions is to automaticly create, delete and
rename files and symlinks like they would be one unit.
*/
#include "mysys_priv.h"
#include "mysys_err.h"
#include <m_string.h>
File my_create_with_symlink(const char *linkname, const char *filename,
int createflags, int access_flags, myf MyFlags)
{
File file;
int tmp_errno;
/* Test if we should create a link */
int create_link;
char abs_linkname[FN_REFLEN];
DBUG_ENTER("my_create_with_symlink");
DBUG_PRINT("enter", ("linkname: %s filename: %s",
linkname ? linkname : "(null)",
filename ? filename : "(null)"));
if (my_disable_symlinks)
{
DBUG_PRINT("info", ("Symlinks disabled"));
/* Create only the file, not the link and file */
create_link= 0;
if (linkname)
filename= linkname;
}
else
{
if (linkname)
my_realpath(abs_linkname, linkname, MYF(0));
create_link= (linkname && strcmp(abs_linkname,filename));
}
if (!(MyFlags & MY_DELETE_OLD))
{
if (!access(filename,F_OK))
{
my_error(EE_CANTCREATEFILE, MYF(0), filename, EEXIST);
DBUG_RETURN(-1);
}
if (create_link && !access(linkname,F_OK))
{
my_error(EE_CANTCREATEFILE, MYF(0), linkname, EEXIST);
DBUG_RETURN(-1);
}
}
if ((file=my_create(filename, createflags, access_flags, MyFlags)) >= 0)
{
if (create_link)
{
/* Delete old link/file */
if (MyFlags & MY_DELETE_OLD)
my_delete(linkname, MYF(0));
/* Create link */
if (my_symlink(filename, linkname, MyFlags))
{
/* Fail, remove everything we have done */
tmp_errno=my_errno;
my_close(file,MYF(0));
my_delete(filename, MYF(0));
file= -1;
my_errno=tmp_errno;
}
}
}
DBUG_RETURN(file);
}
/*
If the file was a symlink, delete both symlink and the file which the
symlink pointed to.
*/
int my_delete_with_symlink(const char *name, myf MyFlags)
{
char link_name[FN_REFLEN];
int was_symlink= (!my_disable_symlinks &&
!my_readlink(link_name, name, MYF(0)));
int result;
DBUG_ENTER("my_delete_with_symlink");
if (!(result=my_delete(name, MyFlags)))
{
if (was_symlink)
result=my_delete(link_name, MyFlags);
}
DBUG_RETURN(result);
}
/*
If the file is a normal file, just rename it.
If the file is a symlink:
- Create a new file with the name 'to' that points at
symlink_dir/basename(to)
- Rename the symlinked file to symlink_dir/basename(to)
- Delete 'from'
If something goes wrong, restore everything.
*/
int my_rename_with_symlink(const char *from, const char *to, myf MyFlags)
{
#ifndef HAVE_READLINK
return my_rename(from, to, MyFlags);
#else
char link_name[FN_REFLEN], tmp_name[FN_REFLEN];
int was_symlink= (!my_disable_symlinks &&
!my_readlink(link_name, from, MYF(0)));
int result=0;
DBUG_ENTER("my_rename_with_symlink");
if (!was_symlink)
DBUG_RETURN(my_rename(from, to, MyFlags));
/* Change filename that symlink pointed to */
strmov(tmp_name, to);
fn_same(tmp_name,link_name,1); /* Copy dir */
/* Create new symlink */
if (my_symlink(tmp_name, to, MyFlags))
DBUG_RETURN(1);
/*
Rename symlinked file if the base name didn't change.
This can happen if you use this function where 'from' and 'to' has
the same basename and different directories.
*/
if (strcmp(link_name, tmp_name) && my_rename(link_name, tmp_name, MyFlags))
{
int save_errno=my_errno;
my_delete(to, MyFlags); /* Remove created symlink */
my_errno=save_errno;
DBUG_RETURN(1);
}
/* Remove original symlink */
if (my_delete(from, MyFlags))
{
int save_errno=my_errno;
/* Remove created link */
my_delete(to, MyFlags);
/* Rename file back */
if (strcmp(link_name, tmp_name))
(void) my_rename(tmp_name, link_name, MyFlags);
my_errno=save_errno;
result= 1;
}
DBUG_RETURN(result);
#endif /* HAVE_READLINK */
}