Commit ff0ecc09 authored by unknown's avatar unknown
Browse files

Merge bk-internal.mysql.com:/home/bk/mysql-5.0

into mysql.com:/home/my/mysql-5.0


innobase/os/os0proc.c:
  Auto merged
parents 06904103 bf01c529
Loading
Loading
Loading
Loading
+56 −25
Original line number Diff line number Diff line
@@ -40,8 +40,18 @@ most significant bytes and bits are written below less significant.

	(1) byte offset		(2) bit usage within byte
	downward from
	origin ->	1	8 bits pointer to next record (relative)
			2	8 bits pointer to next record (relative)
	origin ->	1	8 bits relative offset of next record
			2	8 bits relative offset of next record
				  the relative offset is an unsigned 16-bit
				  integer:
				  (offset_of_next_record
				   - offset_of_this_record) mod 64Ki,
				  where mod is the modulo as a non-negative
				  number;
				  we can calculate the the offset of the next
				  record with the formula:
				  relative_offset + offset_of_this_record
				  mod UNIV_PAGE_SIZE
			3	3 bits status:
					000=conventional record
					001=node pointer record (inside B-tree)
@@ -252,26 +262,37 @@ UNIV_INLINE
ulint 
rec_get_next_offs(
/*==============*/
			/* out: the page offset of the next chained record */
			/* out: the page offset of the next chained record, or
			0 if none */
	rec_t*	rec,	/* in: physical record */
	ibool	comp)	/* in: TRUE=compact page format */
{	
	ulint	field_value;
		
	ut_ad(REC_NEXT_MASK == 0xFFFFUL);
	ut_ad(REC_NEXT_SHIFT == 0);

	field_value = mach_read_from_2(rec - REC_NEXT);

	if (comp) {
		lint ret = (signed short) rec_get_bit_field_2(rec, REC_NEXT,
						REC_NEXT_MASK, REC_NEXT_SHIFT);
#if UNIV_PAGE_SIZE <= 32768
		/* with 64 KiB page size, the pointer will "wrap around",
		and the following assertions are invalid */
		ut_ad(ret + ut_align_offset(rec, UNIV_PAGE_SIZE) <
							UNIV_PAGE_SIZE);
		/* Note that for 64 KiB pages, field_value can 'wrap around'
		and the debug assertion is not valid */

		ut_ad((int16_t)field_value
		       + ut_align_offset(rec, UNIV_PAGE_SIZE)
		      < UNIV_PAGE_SIZE);
#endif
		return(ret ? ut_align_offset(rec + ret, UNIV_PAGE_SIZE) : 0);
		if (field_value == 0) {

			return(0);
		}
	else {
		ulint ret = rec_get_bit_field_2(rec, REC_NEXT,
						REC_NEXT_MASK, REC_NEXT_SHIFT);
		ut_ad(ret < UNIV_PAGE_SIZE);
		return(ret);
		
		return(ut_align_offset(rec + field_value, UNIV_PAGE_SIZE));
	} else {
		ut_ad(field_value < UNIV_PAGE_SIZE);

		return(field_value);
	}
}

@@ -284,21 +305,31 @@ rec_set_next_offs(
/*==============*/
	rec_t*	rec,	/* in: physical record */
	ibool	comp,	/* in: TRUE=compact page format */
	ulint	next)	/* in: offset of the next record */
	ulint	next)	/* in: offset of the next record, or 0 if none */
{
	ut_ad(rec);
	ut_ad(UNIV_PAGE_SIZE > next);
	ut_ad(REC_NEXT_MASK == 0xFFFFUL);
	ut_ad(REC_NEXT_SHIFT == 0);

	if (comp) {
		rec_set_bit_field_2(rec, next
				? (next - ut_align_offset(rec, UNIV_PAGE_SIZE))
#ifdef UNIV_DEBUG /* avoid an assertion failure */
				& (REC_NEXT_MASK >> REC_NEXT_SHIFT)
#endif
				: 0, REC_NEXT, REC_NEXT_MASK, REC_NEXT_SHIFT);
		ulint field_value;

		if (next) {
			/* The following two statements calculate
			next - offset_of_rec mod 64Ki, where mod is the modulo
			as a non-negative number */
		
			field_value = (ulint)((lint)next 
				- (lint)ut_align_offset(rec, UNIV_PAGE_SIZE));
			field_value &= REC_NEXT_MASK;
		} else {
			field_value = 0;
		}

		mach_write_to_2(rec - REC_NEXT, field_value);
	} else {
		rec_set_bit_field_2(rec, next,
				REC_NEXT, REC_NEXT_MASK, REC_NEXT_SHIFT);
		mach_write_to_2(rec - REC_NEXT, next);
	}
}

+12 −4
Original line number Diff line number Diff line
@@ -105,11 +105,19 @@ trx_rollback(
Rollback or clean up transactions which have no user session. If the
transaction already was committed, then we clean up a possible insert
undo log. If the transaction was not yet committed, then we roll it back. 
Note: this is done in a background thread */
Note: this is done in a background thread. */

#ifndef __WIN__
void*
trx_rollback_or_clean_all_without_sess(void *);
/*============================================*/
#else
ulint
#endif
trx_rollback_or_clean_all_without_sess(
/*===================================*/
                        /* out: a dummy parameter */
        void*   arg __attribute__((unused)));
                        /* in: a dummy parameter required by
                        os_thread_create */
/********************************************************************
Finishes a transaction rollback. */

+0 −1
Original line number Diff line number Diff line
@@ -2937,7 +2937,6 @@ recv_recovery_from_checkpoint_finish(void)
#ifndef UNIV_LOG_DEBUG
	recv_sys_free();
#endif

	if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO) {
		os_thread_create(trx_rollback_or_clean_all_without_sess,
				(void *)&i, &recovery_thread_id);
+5 −7
Original line number Diff line number Diff line
@@ -1403,15 +1403,13 @@ NetWare. */
		fsp_header_inc_size(0, sum_of_new_sizes, &mtr);		

		mtr_commit(&mtr);
	}

	if (recv_needed_recovery) {
	    	ut_print_timestamp(stderr);
		fprintf(stderr,
	        "  InnoDB: Flushing modified pages from the buffer pool...\n");
	}
		/* Immediately write the log record about increased tablespace
		size to disk, so that it is durable even if mysqld would crash
		quickly */

	log_make_checkpoint_at(ut_dulint_max, TRUE);
		log_buffer_flush_to_disk();
	}

#ifdef UNIV_LOG_ARCHIVE
	/* Archiving is always off under MySQL */
+51 −18
Original line number Diff line number Diff line
@@ -30,9 +30,13 @@ Created 3/26/1996 Heikki Tuuri
/* This many pages must be undone before a truncate is tried within rollback */
#define TRX_ROLL_TRUNC_THRESHOLD	1

/* In crash recovery, the current trx to be rolled back */
trx_t*		trx_roll_crash_recv_trx	= NULL;

/* In crash recovery we set this to the undo n:o of the current trx to be
rolled back. Then we can print how many % the rollback has progressed. */
ib_longlong	trx_roll_max_undo_no;

/* Auxiliary variable which tells the previous progress % we printed */
ulint		trx_roll_progress_printed_pct;

@@ -332,11 +336,19 @@ trx_savept_take(
Rollback or clean up transactions which have no user session. If the
transaction already was committed, then we clean up a possible insert
undo log. If the transaction was not yet committed, then we roll it back. 
Note: this is done in a background thread */
Note: this is done in a background thread. */

#ifndef __WIN__
void*
trx_rollback_or_clean_all_without_sess(void *i)
/*========================================*/
#else
ulint
#endif
trx_rollback_or_clean_all_without_sess(
/*===================================*/
                        /* out: a dummy parameter */
        void*   arg __attribute__((unused)))
                        /* in: a dummy parameter required by
                        os_thread_create */
{
	mem_heap_t*	heap;
	que_fork_t*	fork;
@@ -361,9 +373,9 @@ trx_rollback_or_clean_all_without_sess(void *i)
	if (UT_LIST_GET_FIRST(trx_sys->trx_list)) {

		fprintf(stderr,
		"InnoDB: Starting rollback of uncommitted transactions\n");
"InnoDB: Starting in background the rollback of uncommitted transactions\n");
	} else {		
		os_thread_exit(i);
		goto leave_function;
	}
loop:
	heap = mem_heap_create(512);
@@ -373,7 +385,6 @@ trx_rollback_or_clean_all_without_sess(void *i)
	trx = UT_LIST_GET_FIRST(trx_sys->trx_list);

	while (trx) {

		if ((trx->sess || (trx->conc_state == TRX_NOT_STARTED))) {
			trx = UT_LIST_GET_NEXT(trx_list, trx);
		} else if (trx->conc_state == TRX_PREPARED) {
@@ -386,17 +397,17 @@ trx_rollback_or_clean_all_without_sess(void *i)
	mutex_exit(&kernel_mutex);

	if (trx == NULL) {
		ut_print_timestamp(stderr);
		fprintf(stderr,
		"  InnoDB: Rollback of uncommitted transactions completed\n");

 		mem_heap_free(heap);

		os_thread_exit(i);
		goto leave_function;
	}

	trx->sess = trx_dummy_sess;

	
	if (trx->conc_state == TRX_COMMITTED_IN_MEMORY) {	
		fprintf(stderr, "InnoDB: Cleaning up trx with id %lu %lu\n",
					(ulong) ut_dulint_get_high(trx->id),
@@ -425,21 +436,28 @@ trx_rollback_or_clean_all_without_sess(void *i)

	ut_a(thr == que_fork_start_command(fork));
	
	trx_roll_crash_recv_trx	= trx;
	trx_roll_max_undo_no = ut_conv_dulint_to_longlong(trx->undo_no);
	trx_roll_progress_printed_pct = 0;
	rows_to_undo = trx_roll_max_undo_no;

	if (rows_to_undo > 1000000000) {
		rows_to_undo = rows_to_undo / 1000000;
		unit = "M";
	}

	ut_print_timestamp(stderr);
	fprintf(stderr,
"InnoDB: Rolling back trx with id %lu %lu, %lu%s rows to undo",
"  InnoDB: Rolling back trx with id %lu %lu, %lu%s rows to undo\n",
					(ulong) ut_dulint_get_high(trx->id),
					(ulong) ut_dulint_get_low(trx->id),
					(ulong) rows_to_undo, unit);
	mutex_exit(&kernel_mutex);

	trx->mysql_thread_id = os_thread_get_curr_id();

	trx->mysql_process_no = os_proc_get_number();

	if (trx->dict_operation) {
		row_mysql_lock_data_dictionary(trx);
	}
@@ -493,9 +511,23 @@ trx_rollback_or_clean_all_without_sess(void *i)
					(ulong) ut_dulint_get_low(trx->id));
	mem_heap_free(heap);

	trx_roll_crash_recv_trx	= NULL;

	goto loop;

	os_thread_exit(i); /* not reached */
leave_function:
	/* We count the number of threads in os_thread_exit(). A created
	thread should always use that to exit and not use return() to exit. */

	os_thread_exit(NULL);

	/* The following is dummy code to keep the compiler happy: */

#ifndef __WIN__
        return(NULL);
#else
        return(0);
#endif
}
	
/***********************************************************************
@@ -856,16 +888,17 @@ trx_roll_pop_top_rec_of_trx(
	ut_ad(ut_dulint_cmp(ut_dulint_add(undo_no, 1), trx->undo_no) == 0);

	/* We print rollback progress info if we are in a crash recovery
	and the transaction has at least 1000 row operations to undo */
	and the transaction has at least 1000 row operations to undo. */

	if (trx == trx_roll_crash_recv_trx && trx_roll_max_undo_no > 1000) {

	if (srv_is_being_started && trx_roll_max_undo_no > 1000) {
	  	progress_pct = 100 - (ulint)
				((ut_conv_dulint_to_longlong(undo_no) * 100)
				/ trx_roll_max_undo_no);
		if (progress_pct != trx_roll_progress_printed_pct) {
			if (trx_roll_progress_printed_pct == 0) {
				fprintf(stderr,
			"\nInnoDB: Progress in percents: %lu", (ulong) progress_pct);
"\nInnoDB: Progress in percents: %lu\n", (ulong) progress_pct);
			} else {
				fprintf(stderr,
				" %lu", (ulong) progress_pct);
Loading