diff options
Diffstat (limited to 'storage/myisam/mi_log.c')
-rw-r--r-- | storage/myisam/mi_log.c | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/storage/myisam/mi_log.c b/storage/myisam/mi_log.c new file mode 100644 index 00000000..9b8405d0 --- /dev/null +++ b/storage/myisam/mi_log.c @@ -0,0 +1,157 @@ +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ + +/* + Logging of MyISAM commands and records on logfile for debugging + The log can be examined with help of the myisamlog command. +*/ + +#include "myisamdef.h" +#ifdef __WIN__ +#include <fcntl.h> +#endif + +#undef GETPID /* For HPUX */ +#define GETPID() (log_type == 1 ? (long) myisam_pid : (long) my_thread_dbug_id()) + + /* Activate logging if flag is 1 and reset logging if flag is 0 */ + +static int log_type=0; +ulong myisam_pid=0; + +int mi_log(int activate_log) +{ + int error=0; + char buff[FN_REFLEN]; + DBUG_ENTER("mi_log"); + + log_type=activate_log; + if (activate_log) + { + if (!myisam_pid) + myisam_pid=(ulong) getpid(); + if (myisam_log_file < 0) + { + if ((myisam_log_file= mysql_file_create(mi_key_file_log, + fn_format(buff, + myisam_log_filename, + "", ".log", 4), + 0, + (O_RDWR | O_BINARY | O_APPEND), + MYF(0))) < 0) + DBUG_RETURN(my_errno); + } + } + else if (myisam_log_file >= 0) + { + error= mysql_file_close(myisam_log_file, MYF(0)) ? my_errno : 0 ; + myisam_log_file= -1; + } + DBUG_RETURN(error); +} + + + /* Logging of records and commands on logfile */ + /* All logs starts with command(1) dfile(2) process(4) result(2) */ + +void _myisam_log(enum myisam_log_commands command, MI_INFO *info, + const uchar *buffert, uint length) +{ + uchar buff[11]; + int error,old_errno; + ulong pid=(ulong) GETPID(); + old_errno=my_errno; + bzero(buff,sizeof(buff)); + buff[0]=(char) command; + mi_int2store(buff+1,info->dfile); + mi_int4store(buff+3,pid); + mi_int2store(buff+9,length); + + mysql_mutex_lock(&THR_LOCK_myisam); + error=my_lock(myisam_log_file,F_WRLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE)); + (void) mysql_file_write(myisam_log_file, buff, sizeof(buff), MYF(0)); + (void) mysql_file_write(myisam_log_file, buffert, length, MYF(0)); + if (!error) + error=my_lock(myisam_log_file,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE)); + mysql_mutex_unlock(&THR_LOCK_myisam); + my_errno=old_errno; +} + + +void _myisam_log_command(enum myisam_log_commands command, MI_INFO *info, + const uchar *buffert, uint length, int result) +{ + uchar buff[9]; + int error,old_errno; + ulong pid=(ulong) GETPID(); + + old_errno=my_errno; + buff[0]=(char) command; + mi_int2store(buff+1,info->dfile); + mi_int4store(buff+3,pid); + mi_int2store(buff+7,result); + mysql_mutex_lock(&THR_LOCK_myisam); + error=my_lock(myisam_log_file,F_WRLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE)); + (void) mysql_file_write(myisam_log_file, buff, sizeof(buff), MYF(0)); + if (buffert) + (void) mysql_file_write(myisam_log_file, buffert, length, MYF(0)); + if (!error) + error=my_lock(myisam_log_file,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE)); + mysql_mutex_unlock(&THR_LOCK_myisam); + my_errno=old_errno; +} + + +void _myisam_log_record(enum myisam_log_commands command, MI_INFO *info, + const uchar *record, my_off_t filepos, int result) +{ + uchar buff[21],*pos; + int error,old_errno; + uint length; + ulong pid=(ulong) GETPID(); + + old_errno=my_errno; + if (!info->s->base.blobs) + length=info->s->base.reclength; + else + length=info->s->base.reclength+ _mi_calc_total_blob_length(info,record); + buff[0]=(uchar) command; + mi_int2store(buff+1,info->dfile); + mi_int4store(buff+3,pid); + mi_int2store(buff+7,result); + mi_sizestore(buff+9,filepos); + mi_int4store(buff+17,length); + mysql_mutex_lock(&THR_LOCK_myisam); + error=my_lock(myisam_log_file,F_WRLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE)); + (void) mysql_file_write(myisam_log_file, buff, sizeof(buff), MYF(0)); + (void) mysql_file_write(myisam_log_file, record, info->s->base.reclength, MYF(0)); + if (info->s->base.blobs) + { + MI_BLOB *blob,*end; + + for (end=info->blobs+info->s->base.blobs, blob= info->blobs; + blob != end ; + blob++) + { + memcpy(&pos, record+blob->offset+blob->pack_length, + sizeof(char*)); + (void) mysql_file_write(myisam_log_file, pos, blob->length, MYF(0)); + } + } + if (!error) + error=my_lock(myisam_log_file,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE)); + mysql_mutex_unlock(&THR_LOCK_myisam); + my_errno=old_errno; +} |