summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <guilhem@gbichot3.local>2007-06-26 22:30:09 +0200
committerunknown <guilhem@gbichot3.local>2007-06-26 22:30:09 +0200
commit1e73169a82f86fa2fdaf43e7601705eb9a81cb85 (patch)
tree5a964e73ff7445d109428aa4193dcb014ca94fb4
parent79672e8c44804fd9b877f51c6e9e054d90ed3d04 (diff)
downloadmariadb-git-1e73169a82f86fa2fdaf43e7601705eb9a81cb85.tar.gz
WL#3072 - Maria recovery
fixes for build failures; copyrights; small bugfixes and comments mysys/Makefile.am: missing .h breaks building from tarball storage/maria/ma_loghandler.c: applying Serg's bugfix of trnman_new_trid() to translog_assign_id_to_share() storage/maria/ma_loghandler.h: copyright storage/maria/ma_loghandler_lsn.h: copyright storage/maria/maria_read_log.c: fix for compiler warnings. Comments. Close tables when program ends.
-rw-r--r--mysys/Makefile.am2
-rw-r--r--storage/maria/ma_loghandler.c35
-rw-r--r--storage/maria/ma_loghandler.h18
-rw-r--r--storage/maria/ma_loghandler_lsn.h15
-rw-r--r--storage/maria/maria_read_log.c66
5 files changed, 106 insertions, 30 deletions
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
index cd84e09a60e..60aa59fd3eb 100644
--- a/mysys/Makefile.am
+++ b/mysys/Makefile.am
@@ -20,7 +20,7 @@ INCLUDES = @ZLIB_INCLUDES@ -I$(top_builddir)/include \
-I$(top_srcdir)/include -I$(srcdir)
pkglib_LIBRARIES = libmysys.a
LDADD = libmysys.a $(top_builddir)/strings/libmystrings.a $(top_builddir)/dbug/libdbug.a
-noinst_HEADERS = mysys_priv.h my_static.h
+noinst_HEADERS = mysys_priv.h my_static.h my_safehash.h
libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
mf_path.c mf_loadpath.c my_file.c \
my_open.c my_create.c my_dup.c my_seek.c my_read.c \
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c
index 6f238ef4055..79bf44046b1 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -177,7 +177,6 @@ my_bool translog_inited= 0;
#include <my_atomic.h>
/* an array that maps id of a MARIA_SHARE to this MARIA_SHARE */
static MARIA_SHARE **id_to_share= NULL;
-#define SHARE_ID_MAX 65535 /* array's size */
/* lock for id_to_share */
static my_atomic_rwlock_t LOCK_id_to_share;
@@ -2282,8 +2281,8 @@ my_bool translog_init(const char *directory,
structures for generating 2-byte ids:
*/
my_atomic_rwlock_init(&LOCK_id_to_share);
- id_to_share= (MARIA_SHARE **) my_malloc(SHARE_ID_MAX*sizeof(MARIA_SHARE*),
- MYF(MY_WME|MY_ZEROFILL));
+ id_to_share= (MARIA_SHARE **) my_malloc(SHARE_ID_MAX * sizeof(MARIA_SHARE*),
+ MYF(MY_WME | MY_ZEROFILL));
if (unlikely(!id_to_share))
DBUG_RETURN(1);
id_to_share--; /* min id is 1 */
@@ -5682,21 +5681,23 @@ int translog_assign_id_to_share(MARIA_SHARE *share, TRN *trn)
if (likely(share->id == 0))
{
/* Inspired by set_short_trid() of trnman.c */
- int i= share->kfile.file % SHARE_ID_MAX + 1;
- my_atomic_rwlock_wrlock(&LOCK_id_to_share);
- /**
- @todo RECOVERY BUG: if all slots are used, and we're using rwlocks
- above, we will never exit the loop. To be discussed with Serg.
- */
- for ( ; ; i= i % SHARE_ID_MAX + 1) /* the range is [1..SHARE_ID_MAX] */
+ uint i= share->kfile.file % SHARE_ID_MAX + 1;
+ do
{
- void *tmp= NULL;
- if (id_to_share[i] == NULL &&
- my_atomic_casptr((void **)&id_to_share[i], &tmp, share))
- break;
- }
- my_atomic_rwlock_wrunlock(&LOCK_id_to_share);
- share->id= (uint16)i;
+ my_atomic_rwlock_wrlock(&LOCK_id_to_share);
+ for ( ; i <= SHARE_ID_MAX ; i++) /* the range is [1..SHARE_ID_MAX] */
+ {
+ void *tmp= NULL;
+ if (id_to_share[i] == NULL &&
+ my_atomic_casptr((void **)&id_to_share[i], &tmp, share))
+ {
+ share->id= (uint16)i;
+ break;
+ }
+ }
+ my_atomic_rwlock_wrunlock(&LOCK_id_to_share);
+ i= 1; /* scan the whole array */
+ } while (share->id == 0);
DBUG_PRINT("info", ("id_to_share: 0x%lx -> %u", (ulong)share, i));
LSN lsn;
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 2];
diff --git a/storage/maria/ma_loghandler.h b/storage/maria/ma_loghandler.h
index 22b8cca3a08..f2bfd2c9d7e 100644
--- a/storage/maria/ma_loghandler.h
+++ b/storage/maria/ma_loghandler.h
@@ -1,4 +1,17 @@
-// TODO copyright
+/* Copyright (C) 2007 MySQL AB & Sanja Belkin
+
+ 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 */
#ifndef _ma_loghandler_h
#define _ma_loghandler_h
@@ -251,6 +264,9 @@ extern my_bool translog_inited;
all the rest added because of recovery; should we make
ma_loghandler_for_recovery.h ?
*/
+
+#define SHARE_ID_MAX 65535 /* array's size */
+
extern LSN first_lsn_in_log();
/* record parts descriptor */
diff --git a/storage/maria/ma_loghandler_lsn.h b/storage/maria/ma_loghandler_lsn.h
index af7594e3b00..34cb7616b74 100644
--- a/storage/maria/ma_loghandler_lsn.h
+++ b/storage/maria/ma_loghandler_lsn.h
@@ -1,3 +1,18 @@
+/* Copyright (C) 2007 MySQL AB & Sanja Belkin
+
+ 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 */
+
#ifndef _ma_loghandler_lsn_h
#define _ma_loghandler_lsn_h
diff --git a/storage/maria/maria_read_log.c b/storage/maria/maria_read_log.c
index e654b8ea2ac..c8263495fbc 100644
--- a/storage/maria/maria_read_log.c
+++ b/storage/maria/maria_read_log.c
@@ -48,7 +48,9 @@ static int display_and_apply_record(const LOG_DESC *log_desc,
#define prototype_exec_hook(R) \
static int exec_LOGREC_ ## R(const TRANSLOG_HEADER_BUFFER *rec)
prototype_exec_hook(LONG_TRANSACTION_ID);
+#ifdef MARIA_CHECKPOINT
prototype_exec_hook(CHECKPOINT);
+#endif
prototype_exec_hook(REDO_CREATE_TABLE);
prototype_exec_hook(FILE_ID);
prototype_exec_hook(REDO_INSERT_ROW_HEAD);
@@ -128,7 +130,9 @@ int main(int argc, char **argv)
log_record_type_descriptor[LOGREC_ ## R].record_execute_in_redo_phase= \
exec_LOGREC_ ## R;
install_exec_hook(LONG_TRANSACTION_ID);
+#ifdef MARIA_CHECKPOINT
install_exec_hook(CHECKPOINT);
+#endif
install_exec_hook(REDO_CREATE_TABLE);
install_exec_hook(FILE_ID);
install_exec_hook(REDO_INSERT_ROW_HEAD);
@@ -337,10 +341,11 @@ static void display_record_position(const LOG_DESC *log_desc,
if number==0, we're going over records which we had already seen and which
form a group, so we indent below the group's end record
*/
- printf("%sRecord #%u LSN (%lu,0x%lx) short_trid %u %s(num_type:%u)\n",
+ printf("%sRec#%u LSN (%lu,0x%lx) short_trid %u %s(num_type:%u) len %lu\n",
number ? "" : " ", number,
(ulong) LSN_FILE_NO(rec->lsn), (ulong) LSN_OFFSET(rec->lsn),
- rec->short_trid, log_desc->name, rec->type);
+ rec->short_trid, log_desc->name, rec->type,
+ (ulong)rec->record_length);
}
@@ -367,6 +372,7 @@ prototype_exec_hook(LONG_TRANSACTION_ID)
TrID long_trid= all_active_trans[sid].long_trid;
/* abort group of this trn (must be of before a crash) */
LSN gslsn= all_active_trans[sid].group_start_lsn;
+ char llbuf[22];
if (gslsn != LSN_IMPOSSIBLE)
{
printf("Group at LSN (%lu,0x%lx) short_trid %u aborted\n",
@@ -378,16 +384,18 @@ prototype_exec_hook(LONG_TRANSACTION_ID)
LSN ulsn= all_active_trans[sid].undo_lsn;
if (ulsn != LSN_IMPOSSIBLE)
{
- fprintf(stderr, "Found an old transaction long_trid %llu short_trid %u"
+ llstr(long_trid, llbuf);
+ fprintf(stderr, "Found an old transaction long_trid %s short_trid %u"
" with same short id as this new transaction, and has neither"
- " committed nor rollback (undo_lsn: (%lu,0x%lx))\n", long_trid,
+ " committed nor rollback (undo_lsn: (%lu,0x%lx))\n", llbuf,
sid, (ulong) LSN_FILE_NO(ulsn), (ulong) LSN_OFFSET(ulsn));
goto err;
}
}
long_trid= uint6korr(rec->header);
all_active_trans[sid].long_trid= long_trid;
- printf("Transaction long_trid %lu short_trid %u starts\n", long_trid, sid);
+ llstr(long_trid, llbuf);
+ printf("Transaction long_trid %s short_trid %u starts\n", llbuf, sid);
goto end;
err:
DBUG_ASSERT(0);
@@ -396,11 +404,14 @@ end:
return 0;
}
+
+#ifdef MARIA_CHECKPOINT
prototype_exec_hook(CHECKPOINT)
{
/* the only checkpoint we care about was found via control file, ignore */
return 0;
}
+#endif
prototype_exec_hook(REDO_CREATE_TABLE)
@@ -600,9 +611,11 @@ prototype_exec_hook(REDO_INSERT_ROW_HEAD)
uint16 sid;
ulonglong page;
MARIA_HA *info;
+ char llbuf[22];
sid= fileid_korr(rec->header);
page= page_korr(rec->header + FILEID_STORE_SIZE);
- printf("For page %llu of table of short id %u", page, sid);
+ llstr(page, llbuf);
+ printf("For page %s of table of short id %u", llbuf, sid);
info= all_tables[sid];
if (info == NULL)
{
@@ -623,6 +636,16 @@ prototype_exec_hook(REDO_INSERT_ROW_HEAD)
assume we have made no checkpoint).
*/
printf(", applying record\n");
+ /*
+ If REDO's LSN is > page's LSN (read from disk), we are going to modify the
+ page and change its LSN. The normal runtime code stores the UNDO's LSN
+ into the page; but here storing the REDO's LSN (rec->lsn) is more
+ straightforward and should not cause any problem (we are not writing to
+ the log here, so don't have to "flush up to UNDO's LSN").
+ If the UNDO's LSN is desired, it can be found, as we saw the UNDO record
+ before deciding to execute this REDO; UNDO's LSN could simply be stored in
+ all_trans[rec->short_trid].group_end_lsn for this.
+ */
DBUG_ASSERT("Monty" == "this is the place");
end:
/* as we don't have apply working: */
@@ -635,14 +658,15 @@ prototype_exec_hook(COMMIT)
uint16 sid= rec->short_trid;
TrID long_trid= all_active_trans[sid].long_trid;
LSN gslsn= all_active_trans[sid].group_start_lsn;
-
+ char llbuf[22];
if (long_trid == 0)
{
printf("We don't know about transaction short_trid %u;"
"it probably committed long ago, forget it\n", sid);
return 0;
}
- printf("Transaction long_trid %lu short_trid %u committed", long_trid, sid);
+ llstr(long_trid, llbuf);
+ printf("Transaction long_trid %s short_trid %u committed", llbuf, sid);
if (gslsn != LSN_IMPOSSIBLE)
{
/*
@@ -671,7 +695,7 @@ prototype_exec_hook(COMMIT)
/* Just to inform about any aborted groups or unfinished transactions */
static void end_of_redo_phase()
{
- uint sid;
+ uint sid, unfinished= 0;
for (sid= 0; sid <= SHORT_TRID_MAX; sid++)
{
TrID long_trid= all_active_trans[sid].long_trid;
@@ -679,8 +703,12 @@ static void end_of_redo_phase()
if (long_trid == 0)
continue;
if (all_active_trans[sid].undo_lsn != LSN_IMPOSSIBLE)
- printf("Transaction long_trid %lu short_trid %u unfinished\n",
- long_trid, sid);
+ {
+ char llbuf[22];
+ llstr(long_trid, llbuf);
+ printf("Transaction long_trid %s short_trid %u unfinished\n",
+ llbuf, sid);
+ }
if (gslsn != LSN_IMPOSSIBLE)
{
printf("Group at LSN (%lu,0x%lx) short_trid %u aborted\n",
@@ -694,4 +722,20 @@ static void end_of_redo_phase()
*/
#endif
}
+ /*
+ We don't close tables if there are some unfinished transactions, because
+ closing tables normally requires that all unfinished transactions on them
+ be rolled back.
+ For example, closing will soon write the state to disk and when doing that
+ it will think this is a committed state, but it may not be.
+ */
+ if (unfinished == 0)
+ {
+ for (sid= 0; sid <= SHORT_TRID_MAX; sid++)
+ {
+ MARIA_HA *info= all_tables[sid];
+ if (info != NULL)
+ maria_close(info);
+ }
+ }
}