We often need to refresh test and development databases with exports that have extent sizing a lot bigger that what we want. In test and ESPECIALLY dev, space and file system availability often require us to just get something working without regard for performance. In these cases, extent sizing in the exports often prevents us from loading even a row-less import into the test/dev database. The following C program was written to deal with those situations. I have used it enough that I think I can go ahead and toss it out to the world. The program is functional but not necessarily elegant. Of course, no guarantees about anything are made. If you make any improvements, I would be most appreciative if you sent them.
====== SNIP ====== SNIP ====== SNIP ====== SNIP ====== SNIP ====== SNIP ====== /*************************************************************** ** This was hastily written by Stephen Lee because we've ** ** been needing something like this real bad for a while. ** ** If you leave the section that opens the files commented, ** ** then the syntax would be something like: ** ** modify_extents < dumpfile > modified_dump_file ** ** ** ** Even though this has been tested against enough exports ** ** that it seems to work OK, I do have some nagging doubts ** ** about how universally compatible it is. I do make some ** ** assumptions about the text in an export dump file and ** ** about the size of a character in that file. ** ** ** ** This program changes the INITIAL and NEXT extent size ** ** specification in the dump file to a fixed size. You can ** ** edit this value in the program, prior to compiling it. ** ** ** ** It is acknowledged that this is a rather bare-bones ** ** program, but it needed to written in a hurry. Enhancement ** ** of the program is left as an exercise for the reader. ** ***************************************************************/ #include <sys/types.h> #include <sys/stat.h> #include <sys/param.h> #include <sys/signal.h> #include <sys/fault.h> #include <sys/syscall.h> #include <sys/procfs.h> #include <dirent.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <pwd.h> #include <math.h> #include <time.h> #include <termios.h> #include <signal.h> #include <ctype.h> #include <netdb.h> /** Include the kitchen sink too **/ /***************** BEGIN MAIN ******************/ int main (int argc, char **argv, char **envp) { int in, out, bytes_read, diddle, match = 0, create = 0; char read_buf[57344], write_buf[65536], diddler; // Note that the following strings contain a space. That is important. char *s0 = "CREATE "; char *s1 = "ALTER "; char *s8 = "INITIAL "; char *s9 = "NEXT "; int s0_len = strlen(s0); int s1_len = strlen(s1); int s8_len = strlen(s8); int s9_len = strlen(s9); int i, j0, j1, j8, j9, x, skip = 0; /*************************************************************************** **** ** Un-comment this section and use the open statements if you want to hard-code ** the paths, or if you want to use something like argv[1] and argv[2]. if( (in = open("/export/oracle/admin/FTLP/exp/test.dmp", O_RDONLY)) < 0 ) { printf("\nFailed to open input file.\n"); return 1; } if( (out = open("/export/oracle/admin/FTLP/exp/modified.dmp", O_RDWR|O_CREAT|O_TRUNC)) < 0 ) { printf("\nFailed to open output file.\n"); return 1; } fchmod(out, 0600); **************************************************************************** / /***** Use the dup commands if you want to use command-line redirection as in: ***** program_name < input_file > output_file ***/ in = dup(0); out = dup(1); /** ** The following loop reads bytes from the input file and copies them to the output file. ** While it is doing this, it is looking for matches to the strings defined in s0, s1, etc. ** S0 and s1 define when we have found the beginning of a CREATE or ALTER command and ** should start looking for the strings INITIAL and NEXT. When those strings are found, ** and we verify that they are followed by a number, then the numeric data is replaced by ** the new characters. Then any following numeric data is skipped until we get to the ** next space. We write the output buffer every time we read a new input buffer. ** We continue this until the entire input file has been read. ** The reason for the CREATE and ALTER searches is to throw in a quart or two of paranoia. ** This requires that both strings CREATE/ALTER and INITIAL/NEXT to be present. I suppose ** there some chance that we could have these strings present, but the line NOT be a line ** that should be modified. But I think the chance is so small as to be insignificant. **/ diddle = j0 = j1 = j8 = j9 = x = 0; diddler = 124; fprintf(stderr,"%c",124); while( (bytes_read = read(in,read_buf,49152)) > 0 ) { for( i = 0; i < bytes_read; ++i ) { // If we have a newline or carriage return, then reset all string searches. if( (read_buf[i] == 10) || (read_buf[i] == 13) ) { j0 = j1 = j8 = j9 = create = skip = match = 0; } // When we are skipping numeric data. if( (skip == 1) && (read_buf[i] != 32) ) continue; // When we were skipping numeric data and have found the next space. if( (skip == 1) && (read_buf[i] == 32) ) skip = 0; // If we found INITIAL or NEXT and it is followed by a number, make the substitution. if( (match == 1) && (read_buf[i] > 47) && (read_buf[i] < 58) ) { write_buf[x++] = '2'; write_buf[x++] = 'M'; j8 = j9 = match = 0; skip = 1; continue; } else match = 0; // Copy input buffer to output buffer write_buf[x++] = read_buf[i]; // Look for CREATE or ALTER if( read_buf[i] == s0[j0] ) ++j0; else j0 = 0; if( read_buf[i] == s1[j1] ) ++j1; else j1 = 0; if( (j0 == s0_len) || (j1 == s1_len) ) { create = 1; continue; } if( create == 0 ) continue; // Look for INITIAL or NEXT if( read_buf[i] == s8[j8] ) ++j8; else j8 = 0; if( read_buf[i] == s9[j9] ) ++j9; else j9 = 0; if( (j8 == s8_len) || (j9 == s9_len) ) match = 1; } write(out,write_buf,x+0); if( diddle == 50 ) { if( diddler == 124 ) { fprintf(stderr,"%c%c",8,47); diddler = 47; } else if( diddler == 47 ) { fprintf(stderr, "%c%c",8,45); diddler = 45; } else if( diddler == 45 ) { fprintf(stderr, "%c%c",8,92); diddler = 92; } else if( diddler == 92 ) { fprintf(stderr, "%c%c",8,124); diddler = 124; } diddle = 0; } ++diddle; x = 0; } fprintf(stderr,"\n"); /** If you have used open function and want to be clean and tidy. close(in); close(out); **/ return 0; } /***************** END MAIN ******************/ -- Please see the official ORACLE-L FAQ: http://www.orafaq.com -- Author: Stephen Lee INET: [EMAIL PROTECTED] Fat City Network Services -- 858-538-5051 http://www.fatcity.com San Diego, California -- Mailing list and web hosting services --------------------------------------------------------------------- To REMOVE yourself from this mailing list, send an E-Mail message to: [EMAIL PROTECTED] (note EXACT spelling of 'ListGuru') and in the message BODY, include a line containing: UNSUB ORACLE-L (or the name of mailing list you want to be removed from). You may also send the HELP command for other information (like subscribing).