Re: replacing mounted rootdbs as raw diskspace
Posted in 1998
This is a multi-part message in MIME format.
--------------6B2046C026FB289F65946785
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
sukumar konduru wrote:
>
> Hi
>
> Our "rootdbs" has been created as mounted file system rather than raw
> disk space. Our database is in another dbspace which is created as raw
> diskspace.
>
> Is it really improves performance if we use raw diskspace rather than
> unix file system?. What are the
> steps needed in migrating root dbs as raw disk space?
>
> Thank you
>
> Sukumar Konduru
Hi Sukumar,
concerning your first question, "will a raw device help improving
the performance ?" :
Generally the answer is yes. But all your data is already on a
raw device. I guess that only the logical log files and the
physical log file resides in your rootdbs, that means that
there might be just a few writes and reads to your rootdbs.
If you are using version 7.x and set your DBSPACETEMP parameter
to the datadbs, then there are just a few additional pages inside
the rootdbs that will be touched during runtime, because your
databases reside in your datadbs.
Have a look at the relation between datadbs-I/O and rootdbs-I/O:
onstat -D
will show you the number of pages read from and written to a chunk.
My exapmle:
I assume that the pages written to the filesystem-chunk are
10,000 pages and you read about 5,000 pages. ( just an example )
This would be the amount of data written per day.
Now it's interesting to calculate the speedup, because I think
it makes no sense to spend a lot of spare time for nothing :-))
How long does it take to write 10000 pages to the filesystem,
and how long does it take to write 10000 pages to a raw-device ?
The following is just for incurable nerds - skip it if you want !
( The smallest I/O unit is the page. Logical Log Files and the
Phyiscal Log are always written in buffered mode ( using the
logical log buffer/physical log buffer ). Let's say the
average load factor of this buffers would be 75%, as Informix
recommends. In this "normal" case we would write not page
by page, but about 32KB (default size) * 0.75 ~ 24KB per write. )
Okay, now the test. To compare both writes we must write a small
C-program, because I didn't find an appropriate option for "dd"
to open the filesystem chunk with the option O_SYNC. But the
C-Program is very easy to understand. ( It's late in the evening
here in Germany, but I will do my very best ... )
I'll append the C-source at the end of this reply.
On my platform it took 10seconds to write 10MB on a raw device,
and about 67seconds to perform the same write on a cooked file.
I hope Informix does not read page by page when they perform a
rollback. I guess they read about 16KB or more. The filesystem
does always read 16KB or more, even if you just want 2KB.
( That's what I saw on most platforms. )
So the speed to read data from the logical/physical log must
be approximately the same.
If we assume a page size of 2KB then we would save about 114 seconds
per day if we would use a raw-device instead of a cooked-file.
10,000 x 2KB pages ~ 20,000KB would take about 134seconds on a cooked
file.
The same amount of KB would cost about 20 seconds on a raw-device.
In the worst case of unbuffered logged databases ( buffer must be
flushed to disk before programmer will get the okay ) you would
save 134seconds - 20seconds = 114seconds. This is just an example,
but possibly you wonder why you don't recognize the speedup.
Bye
Stefan Weideneder
PS: Concerning your second question - how can it be done, look
at Art S. Kagel's reply.
--------------6B2046C026FB289F65946785
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="iotest.c"
/*
* A small test program to measure the speed
* of your cooked-file chunk. Usage:
*
* iotest -b 8192 -c 1250 /tmp/file
*
* writes 1250 blocks, each of size 8192 byte to /tmp/file.
* The resulting real time will be displayed.
* The file must be available.
*
*/
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
/*
* If prototyping bothers you, remove the next two lines.
* It's just to avoid warnings on a few compilers.
*/
int RunTest( char*, int, int );
void usage( char * );
void
usage( prog_pc )
char *prog_pc;
{
fprintf( stderr, "usage: %s [-b blocksize] -c nblocks filename\\n", prog_pc );
exit( 1 );
}
void
main( argc, argv )
int argc;
char **argv;
{
int blocksize_i = 2048; /* default block size I use */
int count_i = 0; /* number of blocks to write */
char *filename_pc = NULL; /* the specific filename */
char *ptr_pc; /* every C-program needs a ptr */
int i;
for ( i = 1; i < argc; i++ )
{
if ( *argv[ i ] == '-' )
{
switch( *( argv[ i ] + 1 ) )
{
case 'b':
if ( *( ptr_pc = ( argv[ i ] + 2 ) ) == 0x00 )
ptr_pc = argv[ ++i ];
if ( ptr_pc == NULL ||
( blocksize_i = atoi( ptr_pc ) ) == 0 )
{
usage( argv[ 0 ] );
}
break;
case 'c':
if ( *( ptr_pc = ( argv[ i ] + 2 ) ) == 0x00 )
ptr_pc = argv[ ++i ];
if ( ptr_pc == NULL ||
( count_i = atoi( ptr_pc ) ) == 0 )
{
usage( argv[ 0 ] );
}
break;
default:
usage( argv[ 0 ] );
}
}
else if ( ! filename_pc )
filename_pc = argv[ i ];
else
usage( argv[ 0 ] );
}
if ( count_i == 0 || filename_pc == NULL )
usage( argv[ 0 ] );
exit( RunTest( filename_pc, count_i, blocksize_i ) );
}
int
RunTest( file_pc, count_i, bs_i )
char *file_pc;
int count_i;
int bs_i;
{
int status = 0; /* my return code */
int fd_i = -1; /* my file descriptor */
int sync_i = 0; /* sync option for open call */
int i;
struct stat st_s; /* status of the file */
char *ptr_pc = NULL; /* the block buffer */
time_t lt_s; /* start time */
if ( stat( file_pc, &st_s ) == -1 )
{
fprintf( stderr, "cannot stat file '%s'. errno = %d\\n", file_pc,
status = errno );
return( status );
}
else if ( S_ISBLK( st_s.st_mode ) || S_ISREG( st_s.st_mode ) )
{
sync_i = O_SYNC;
}
else if ( ! S_ISCHR( st_s.st_mode ) )
{
fprintf( stderr, "'%s' filetype not supported for a chunk\\n", file_pc );
return( status = EINVAL );
}
/*
* allocate the buffer
*/
ptr_pc = (char*)malloc( bs_i );
if ( ! ptr_pc )
{
status = errno;
fprintf( stderr, "cannot allocate the %d byte buffer.\\n", bs_i );
return( status );
}
/*
* Now open the file. Don't forget the O_SYNC option for ordinary files
* and block devices.
*/
fd_i = open( file_pc, O_WRONLY | sync_i );
if ( fd_i < 0 )
{
status = errno;
fprintf( stderr,