mirror of
https://github.com/MariaDB/server.git
synced 2025-01-30 18:41:56 +01:00
d6f2fda680
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''
172 lines
4.7 KiB
C
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 */
|
|
}
|