truncating redo log file instead of removing it
[csql.git] / src / sqllog / FileSend.cxx
bloba6b417361d71c2f28d5cd16287050e52e9a46f28
1 /***************************************************************************
2 * Copyright (C) 2007 by Prabakaran Thirumalai *
3 * praba_tuty@yahoo.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #include <os.h>
21 #include <SqlLogConnection.h>
22 #include <CSql.h>
24 FileSend::FileSend()
26 openRedoFile();
28 DbRetVal FileSend::openRedoFile()
30 char fileName[MAX_FILE_LEN];
31 sprintf(fileName, "%s/csql.db.cur", Conf::config.getDbFile());
32 int durableMode = Conf::config.getDurableMode();
33 switch(durableMode) {
34 case 1:
35 case 2:
36 fdRedoLog = os::openFileForAppend(fileName, O_CREAT);
37 break;
38 case 3:
39 fdRedoLog = os::openFileForAppend(fileName, O_CREAT|O_SYNC);
40 break;
41 case 4:
42 #ifdef SOLARIS
43 fdRedoLog = os::openFileForAppend(fileName, O_CREAT|O_DSYNC);
44 #else
45 fdRedoLog = os::openFileForAppend(fileName, O_CREAT|O_DIRECT);
46 #endif
47 break;
48 default:
49 fdRedoLog = os::openFileForAppend(fileName, O_CREAT);
50 break;
52 if (-1 == fdRedoLog) {
53 printError(ErrSysInternal, "Unable to open redo log file");
54 return ErrSysInternal;
56 return OK;
59 FileSend::~FileSend() { if (fdRedoLog > 0) os::closeFile(fdRedoLog); fdRedoLog = -1; }
61 DbRetVal FileSend::prepare(int txnId, int stmtId, int len, char *stmt, char *tblName)
63 if (fdRedoLog < 0) return ErrBadArg;
64 //The following structure needs strlen after stmt id for traversal in
65 //redolog file unlike msg queue structure where string is the last element
66 //and is not a continuous piece of memory.
67 int datalen = os::align(5 * sizeof(int) + len); // for len + txnId + msg type + stmtId + tableName + stmtstrlen + stmtstring
68 char *buf = (char*) malloc(datalen);
69 char *msg = buf;
70 //Note:: msg type is taken as -ve as we need to differentiate between
71 //statement id and logtype during recovery.
72 *(int*) msg = -1;
73 if (strlen(stmt) > 6 && ( strncasecmp(stmt,"CREATE", 6) == 0 || strncasecmp(stmt,"DROP", 4) == 0 ))
74 *(int*)msg = -4; //means prepare and execute the stmt
75 msg = msg+sizeof(int);
76 *(int *)msg = datalen;
77 msg = msg+sizeof(int);
78 *(int *)msg = txnId;
79 msg = msg+sizeof(int);
80 *(int *)msg = stmtId;
81 msg = msg+ sizeof(int);
82 *(int *)msg = os::align(len);
83 msg = msg+ sizeof(int);
84 msg[len-1] = '\0';
85 strcpy(msg, stmt);
86 int ret =0;
87 bool firstTime=true;
88 retry:
89 if (Conf::config.getDurableMode() != 1) {
90 ret = os::lockFile(fdRedoLog);
91 if (-1 == ret) {
92 ::free(buf);
93 printError(ErrLockTimeOut,"Unable to get exclusive lock on redo log file");
94 return ErrLockTimeOut;
97 ret = os::write(fdRedoLog, buf, datalen);
98 if (Conf::config.getDurableMode() != 1) {
99 os::unlockFile(fdRedoLog);
101 if (-1 == ret) {
102 DbRetVal rv = openRedoFile();
103 if (OK == rv) {
104 logFine(Conf::logger, "Reopening redo log file");
105 if(firstTime) { firstTime = false; goto retry; }
107 printError(ErrOS, "Unable to write undo log");
108 ::free(buf);
109 return ErrOS;
111 ::free(buf);
112 return OK;
115 DbRetVal FileSend::commit(int len, void *data)
117 if (fdRedoLog < 0) return ErrBadArg;
118 char *dat=(char*)data - sizeof(int);
119 *(int*)dat = -2; //type 2->commit
120 bool firstTime = true;
121 retry:
122 if (Conf::config.getDurableMode() != 1) {
123 int ret = os::lockFile(fdRedoLog);
124 if (-1 == ret) {
125 printError(ErrLockTimeOut,"Unable to get exclusive lock on redo log file");
126 return ErrLockTimeOut;
129 int ret = os::write(fdRedoLog, dat, len+sizeof(int));
130 if (Conf::config.getDurableMode() != 1) {
131 os::unlockFile(fdRedoLog);
133 if (-1 == ret) {
134 DbRetVal rv = openRedoFile();
135 if (OK == rv) {
136 logFine(Conf::logger, "Reopening redo log file");
137 if(firstTime) { firstTime = false; goto retry; }
139 printError(ErrOS, "Unable to write undo log");
140 return ErrOS;
142 return OK;
144 DbRetVal FileSend::free(int txnId, int stmtId)
146 int buflen = 4 *sizeof(int);
147 char *msg = (char *) malloc(buflen);
148 char *ptr = msg;
149 *(int*)ptr = -3;
150 ptr += sizeof(int);
151 *(int *)ptr = 3 * sizeof(int); // for len + txnId + stmtId
152 ptr += sizeof(int);
153 *(int *)ptr = txnId;
154 ptr += sizeof(int);
155 *(int *)ptr = stmtId;
156 printDebug(DM_SqlLog, "stmtID sent = %d\n", *(int *)ptr);
157 bool firstTime = false;
158 retry:
159 if (Conf::config.getDurableMode() != 1) {
160 int ret = os::lockFile(fdRedoLog);
161 if (-1 == ret) {
162 ::free(msg);
163 printError(ErrLockTimeOut,"Unable to get exclusive lock on redo log file");
164 return ErrLockTimeOut;
167 int ret = os::write(fdRedoLog, msg, buflen);
168 if (Conf::config.getDurableMode() != 1) {
169 os::unlockFile(fdRedoLog);
171 if (-1 == ret) {
172 DbRetVal rv = openRedoFile();
173 if (OK == rv) {
174 logFine(Conf::logger, "Reopening redo log file");
175 if(firstTime) { firstTime = false; goto retry; }
177 printError(ErrOS, "Unable to write undo log");
178 ::free(msg);
179 return ErrOS;
181 ::free(msg);
182 return OK;