Commit 1084e540 authored by unknown's avatar unknown
Browse files

InnoDB: Optimize the extension of files. This will greatly speed

up CREATE TABLE in innodb_file_per_table=1 mode.


innobase/fil/fil0fil.c:
  fil_extend_space_to_desired_size(): Do not allocate or initialize
  more memory than is necessary.  Write at most one megabyte at a time.
innobase/include/os0file.h:
  os_file_set_size(): Corrected the synopsis
innobase/os/os0file.c:
  os_file_set_size(): Corrected the synopsis and some comments.
  s/offset/current_size; s/low/desired_size/;
  Do not allocate or initialize more memory than is necessary.
  Write at most one megabyte at a time.
parent e00981bb
Loading
Loading
Loading
Loading
+11 −13
Original line number Diff line number Diff line
@@ -3400,9 +3400,9 @@ fil_extend_space_to_desired_size(
	fil_space_t*	space;
	byte*		buf2;
	byte*		buf;
	ulint		buf_size;
	ulint		start_page_no;
	ulint		file_start_page_no;
	ulint		n_pages;
	ulint		offset_high;
	ulint		offset_low;
	ibool		success		= TRUE;
@@ -3427,22 +3427,20 @@ fil_extend_space_to_desired_size(

	fil_node_prepare_for_io(node, system, space);

	/* Extend 1 MB at a time */
	start_page_no = space->size;
	file_start_page_no = space->size - node->size;

	buf2 = mem_alloc(1024 * 1024 + UNIV_PAGE_SIZE);
	/* Extend at most 64 pages at a time */
	buf_size = ut_min(64, size_after_extend - start_page_no)
				* UNIV_PAGE_SIZE;
	buf2 = mem_alloc(buf_size + UNIV_PAGE_SIZE);
	buf = ut_align(buf2, UNIV_PAGE_SIZE);

	memset(buf, '\0', 1024 * 1024);

	start_page_no = space->size;
	file_start_page_no = space->size - node->size;
	memset(buf, 0, buf_size);

	while (start_page_no < size_after_extend) {
		n_pages = size_after_extend - start_page_no;

		if (n_pages > (1024 * 1024) / UNIV_PAGE_SIZE) {
			n_pages = (1024 * 1024) / UNIV_PAGE_SIZE;
		}
		ulint	n_pages = ut_min(buf_size / UNIV_PAGE_SIZE,
				size_after_extend - start_page_no);

		offset_high = (start_page_no - file_start_page_no)
				/ (4096 * ((1024 * 1024) / UNIV_PAGE_SIZE));
+1 −1
Original line number Diff line number Diff line
@@ -368,7 +368,7 @@ os_file_get_size_as_iblonglong(
				/* out: size in bytes, -1 if error */
	os_file_t	file);	/* in: handle to a file */
/***************************************************************************
Sets a file size. This function can be used to extend or truncate a file. */
Write the specified number of zeros to a newly created file. */

ibool
os_file_set_size(
+21 −29
Original line number Diff line number Diff line
@@ -1642,7 +1642,7 @@ os_file_get_size_as_iblonglong(
}

/***************************************************************************
Sets a file size. This function can be used to extend or truncate a file. */
Write the specified number of zeros to a newly created file. */

ibool
os_file_set_size(
@@ -1655,47 +1655,39 @@ os_file_set_size(
				size */
	ulint		size_high)/* in: most significant 32 bits of size */
{
	ib_longlong	offset;
	ib_longlong	low;
	ulint   	n_bytes;
	ib_longlong	current_size;
	ib_longlong	desired_size;
	ibool		ret;
	byte*   	buf;
	byte*   	buf2;
	ulint   	i;
	ulint		buf_size;

	ut_a(size == (size & 0xFFFFFFFF));

	/* We use a very big 8 MB buffer in writing because Linux may be
	extremely slow in fsync on 1 MB writes */
	current_size = 0;
	desired_size = (ib_longlong)size + (((ib_longlong)size_high) << 32);

	buf2 = ut_malloc(UNIV_PAGE_SIZE * 513);
	/* Write up to 1 megabyte at a time. */
	buf_size = ut_min(UNIV_PAGE_SIZE * 64, desired_size);
	buf2 = ut_malloc(buf_size + UNIV_PAGE_SIZE);

	/* Align the buffer for possible raw i/o */
	buf = ut_align(buf2, UNIV_PAGE_SIZE);

	/* Write buffer full of zeros */
	for (i = 0; i < UNIV_PAGE_SIZE * 512; i++) {
	        buf[i] = '\0';
	}

	offset = 0;
	low = (ib_longlong)size + (((ib_longlong)size_high) << 32);
	memset(buf, 0, buf_size);

	if (low >= (ib_longlong)(100 * 1024 * 1024)) {
	if (desired_size >= (ib_longlong)(100 * 1024 * 1024)) {
				
		fprintf(stderr, "InnoDB: Progress in MB:");
	}

	while (offset < low) {
	        if (low - offset < UNIV_PAGE_SIZE * 512) {
	        	n_bytes = (ulint)(low - offset);
	        } else {
	        	n_bytes = UNIV_PAGE_SIZE * 512;
	        }
	  
	while (current_size < desired_size) {
		ulint	n_bytes = ut_min(buf_size,
				(ulint) (desired_size - current_size));
	        ret = os_file_write(name, file, buf,
				(ulint)(offset & 0xFFFFFFFF),
				    (ulint)(offset >> 32),
				(ulint)(current_size & 0xFFFFFFFF),
				    (ulint)(current_size >> 32),
				n_bytes);
	        if (!ret) {
			ut_free(buf2);
@@ -1703,18 +1695,18 @@ os_file_set_size(
	        }
				
		/* Print about progress for each 100 MB written */
		if ((offset + n_bytes) / (ib_longlong)(100 * 1024 * 1024)
		    != offset / (ib_longlong)(100 * 1024 * 1024)) {
		if ((current_size + n_bytes) / (ib_longlong)(100 * 1024 * 1024)
		    != current_size / (ib_longlong)(100 * 1024 * 1024)) {

		        fprintf(stderr, " %lu00",
				(ulong) ((offset + n_bytes)
				(ulong) ((current_size + n_bytes)
					/ (ib_longlong)(100 * 1024 * 1024)));
		}
		
	        offset += n_bytes;
	        current_size += n_bytes;
	}

	if (low >= (ib_longlong)(100 * 1024 * 1024)) {
	if (desired_size >= (ib_longlong)(100 * 1024 * 1024)) {
				
		fprintf(stderr, "\n");
	}