Beispiel #1
0
/*
 * __wt_log_system_record --
 *	Write a system log record for the previous LSN.
 */
int
__wt_log_system_record(
    WT_SESSION_IMPL *session, WT_FH *log_fh, WT_LSN *lsn)
{
	WT_DECL_ITEM(logrec_buf);
	WT_DECL_RET;
	WT_LOG *log;
	WT_LOG_RECORD *logrec;
	WT_LOGSLOT tmp;
	WT_MYSLOT myslot;
	const char *fmt = WT_UNCHECKED_STRING(I);
	uint32_t rectype = WT_LOGREC_SYSTEM;
	size_t recsize;

	log = S2C(session)->log;
	WT_RET(__wt_logrec_alloc(session, log->allocsize, &logrec_buf));
	memset((uint8_t *)logrec_buf->mem, 0, log->allocsize);

	WT_ERR(__wt_struct_size(session, &recsize, fmt, rectype));
	WT_ERR(__wt_struct_pack(session,
	    (uint8_t *)logrec_buf->data + logrec_buf->size, recsize, fmt,
	    rectype));
	logrec_buf->size += recsize;
	WT_ERR(__wt_logop_prev_lsn_pack(session, logrec_buf, lsn));
	WT_ASSERT(session, logrec_buf->size <= log->allocsize);

	logrec = (WT_LOG_RECORD *)logrec_buf->mem;

	/*
	 * We know system records are this size.  And we have to adjust
	 * the size now because we're not going through the normal log
	 * write path and the packing functions needed the correct offset
	 * earlier.
	 */
	logrec_buf->size = logrec->len = log->allocsize;

	/* We do not compress nor encrypt this record. */
	logrec->checksum = 0;
	logrec->flags = 0;
	__wt_log_record_byteswap(logrec);
	logrec->checksum = __wt_checksum(logrec, log->allocsize);
#ifdef WORDS_BIGENDIAN
	logrec->checksum = __wt_bswap32(logrec->checksum);
#endif
	WT_CLEAR(tmp);
	memset(&myslot, 0, sizeof(myslot));
	myslot.slot = &tmp;
	__wt_log_slot_activate(session, &tmp);
	/*
	 * Override the file handle to the one we're using.
	 */
	tmp.slot_fh = log_fh;
	WT_ERR(__wt_log_fill(session, &myslot, true, logrec_buf, NULL));
err:	__wt_logrec_free(session, &logrec_buf);
	return (ret);
}
Beispiel #2
0
/*
 * __wt_log_slot_init --
 *	Initialize the slot array.
 */
int
__wt_log_slot_init(WT_SESSION_IMPL *session, bool alloc)
{
	WT_CONNECTION_IMPL *conn;
	WT_DECL_RET;
	WT_LOG *log;
	WT_LOGSLOT *slot;
	int32_t i;

	conn = S2C(session);
	log = conn->log;
	for (i = 0; i < WT_SLOT_POOL; i++)
		log->slot_pool[i].slot_state = WT_LOG_SLOT_FREE;

	/*
	 * Allocate memory for buffers now that the arrays are setup. Separate
	 * this from the loop above to make error handling simpler.
	 */
	/*
	 * !!! If the buffer size is too close to the log file size, we will
	 * switch log files very aggressively.  Scale back the buffer for
	 * small log file sizes.
	 */
	if (alloc) {
		log->slot_buf_size = (uint32_t)WT_MIN(
		    (size_t)conn->log_file_max / 10, WT_LOG_SLOT_BUF_SIZE);
		for (i = 0; i < WT_SLOT_POOL; i++) {
			WT_ERR(__wt_buf_init(session,
			    &log->slot_pool[i].slot_buf, log->slot_buf_size));
			F_SET(&log->slot_pool[i], WT_SLOT_INIT_FLAGS);
		}
		WT_STAT_CONN_SET(session,
		    log_buffer_size, log->slot_buf_size * WT_SLOT_POOL);
	}
	/*
	 * Set up the available slot from the pool the first time.
	 */
	slot = &log->slot_pool[0];
	/*
	 * We cannot initialize the release LSN in the activate function
	 * because that function can be called after a log file switch.
	 * The release LSN is usually the same as the slot_start_lsn except
	 * around a log file switch.
	 */
	slot->slot_release_lsn = log->alloc_lsn;
	__wt_log_slot_activate(session, slot);
	log->active_slot = slot;
	log->pool_index = 0;

	if (0) {
err:		while (--i >= 0)
			__wt_buf_free(session, &log->slot_pool[i].slot_buf);
	}
	return (ret);
}