-
Notifications
You must be signed in to change notification settings - Fork 84
/
dbrollfwd.sqC
311 lines (262 loc) · 11.4 KB
/
dbrollfwd.sqC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
/****************************************************************************
** (c) Copyright IBM Corp. 2007 All rights reserved.
**
** The following sample of source code ("Sample") is owned by International
** Business Machines Corporation or one of its subsidiaries ("IBM") and is
** copyrighted and licensed, not sold. You may use, copy, modify, and
** distribute the Sample in any form without payment to IBM, for the purpose of
** assisting you in the development of your applications.
**
** The Sample code is provided to you on an "AS IS" basis, without warranty of
** any kind. IBM HEREBY EXPRESSLY DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR
** IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Some jurisdictions do
** not allow for the exclusion or limitation of implied warranties, so the above
** limitations or exclusions may not apply to you. IBM shall not be liable for
** any damages you suffer as a result of using, copying, modifying or
** distributing the Sample, even if IBM has been advised of the possibility of
** such damages.
*****************************************************************************
**
** SOURCE FILE NAME: dbrollfwd.sqC
**
** SAMPLE: How to recover a database using rollforward recovery.
**
** Note:
** You must be disconnected from the sample database to run
** this program. To ensure that you are disconnected, enter
** 'db2 connect reset'
** on the command line prior to running dbrollfwd.
**
** DB2 APIs USED:
** db2CfgSet -- Set Configuration
** db2Restore -- Restore Database
** db2Rollforward -- Rollforward Database
**
** OUTPUT FILE: dbrollfwd.out (available in the online documentation)
*****************************************************************************
**
** For detailed information about database backup and database recovery, see
** the Data Recovery and High Availability Guide and Reference. This manual
** will help you to determine which database and table space recovery methods
** are best suited to your business environment.
**
** For more information on the sample programs, see the README file.
**
** For information on developing C++ applications, see the Application
** Development Guide.
**
** For information on using SQL statements, see the SQL Reference.
**
** For information on DB2 APIs, see the Administrative API Reference.
**
** For the latest information on programming, building, and running DB2
** applications, visit the DB2 application development website:
** http://www.software.ibm.com/data/db2/udb/ad
****************************************************************************/
#ifdef DB2NT
#include "utilrecov.cxx"
#else
#include "utilrecov.C"
#endif
class DbRollFwd: public UtilRecov
{
public:
int DbBackupRestoreAndRollforward(DbEmb *, DbEmb *, char *);
};
int DbRollFwd::DbBackupRestoreAndRollforward(DbEmb *db,
DbEmb *rolledForwardDb,
char serverWorkingPath[])
{
int rc = 0;
struct sqlca sqlca = { 0 };
char logretain[]= "LOGRETAIN";
db2CfgParam cfgParameters[1] = { 0 };
db2Cfg cfgStruct = { 0 };
char restoreTimestamp[SQLU_TIME_STAMP_LEN + 1] = { 0 };
db2BackupStruct backupStruct = { 0 };
db2TablespaceStruct tablespaceStruct = { 0 };
db2MediaListStruct mediaListStruct = { 0 };
db2Uint32 backupImageSize = 0;
db2RestoreStruct restoreStruct = { 0 };
db2TablespaceStruct rtablespaceStruct = { 0 };
db2MediaListStruct rmediaListStruct = { 0 };
db2RfwdInputStruct rfwdInput = { 0 };
db2RfwdOutputStruct rfwdOutput = { 0 };
db2RollforwardStruct rfwdStruct = { 0 };
char rollforwardAppId[SQLU_APPLID_LEN + 1] = { 0 };
sqlint32 numReplies = 0;
struct sqlurf_info nodeInfo = { 0 };
cout << "\n****************************\n";
cout << "*** ROLLFORWARD RECOVERY ***\n";
cout << "****************************\n";
cout << "\n-----------------------------------------------------------";
cout << "\nUSE THE DB2 APIs:" << endl;
cout << " db2CfgSet -- SET CONFIGURATION" << endl;
cout << " db2Backup -- BACKUP DATABASE" << endl;
cout << " sqlecrea -- CREATE DATABASE" << endl;
cout << " db2Restore -- RESTORE DATABASE" << endl;
cout << " db2Rollforward -- ROLLFORWARD DATABASE" << endl;
cout << " sqledrpd -- DROP DATABASE" << endl;
cout << "TO BACKUP, RESTORE AND ROLLFORWARD A DATABASE." << endl;
// Update db config: set logarchmeth1 = LOGRETAIN
cout << "\n Update \'" << db->getAlias() << "\' database configuration:\n";
cout << " - Enable the database configuration parameter LOGARCHMETH1 \n";
cout << " i.e., set LOGARCHMETH1 = LOGRETAIN \n";
cfgParameters[0].flags = 0;
cfgParameters[0].token = SQLF_DBTN_LOGARCHMETH1;
cfgParameters[0].ptrvalue = (char *)&logretain;
// logretain = SQLF_LOGRETAIN_RECOVERY;
// Initialize cfgStruct
cfgStruct.numItems = 1;
cfgStruct.paramArray = cfgParameters;
cfgStruct.flags = db2CfgDatabase | db2CfgDelayed;
cfgStruct.dbname = db->getAlias();
// Set database configuration
db2CfgSet(db2Version1010, (void *)&cfgStruct, &sqlca);
DB2_API_CHECK("Db Log ArchMeth1 -- Enable");
rc = sqle_deactivate_db (db->getAlias(),
NULL,
NULL,
NULL,
&sqlca);
//****************************
// BACKUP THE DATABASE
//****************************
// Calling the routine for database backup
rc = DbBackup(db, serverWorkingPath, &backupStruct);
CHECKRC(rc, "DbBackup");
// To restore a remote database, you will first need to create an empty
// database if the client's code page is different from the server's code
// page. If this is the case, uncomment the call to DbCreate(). It will
// create an empty database on the server with the server's code page.
// rc = DbCreate(db->getAlias(), rolledForwardDb->getAlias());
// CHECKRC(rc, "DbCreate");
// Start the restore process
strcpy(restoreTimestamp, backupStruct.oTimestamp);
rtablespaceStruct.tablespaces = NULL;
rtablespaceStruct.numTablespaces = 0;
rmediaListStruct.locations = &serverWorkingPath;
rmediaListStruct.numLocations = 1;
rmediaListStruct.locationType = SQLU_LOCAL_MEDIA;
restoreStruct.piSourceDBAlias = db->getAlias();
restoreStruct.piTargetDBAlias = rolledForwardDb->getAlias();
restoreStruct.piTimestamp = restoreTimestamp;
restoreStruct.piTargetDBPath = NULL;
restoreStruct.piReportFile = NULL;
restoreStruct.piTablespaceList = &rtablespaceStruct;
restoreStruct.piMediaList = &rmediaListStruct;
restoreStruct.piUsername = db->getUser();
restoreStruct.piPassword = db->getPswd();
restoreStruct.piNewLogPath = NULL;
restoreStruct.piVendorOptions = NULL;
restoreStruct.iVendorOptionsSize = 0;
restoreStruct.iParallelism = 1;
restoreStruct.iBufferSize = 1024; /* 1024 x 4KB */
restoreStruct.iNumBuffers = 2;
restoreStruct.iCallerAction = DB2RESTORE_RESTORE;
restoreStruct.iOptions =
DB2RESTORE_OFFLINE | DB2RESTORE_DB | DB2RESTORE_NODATALINK |
DB2RESTORE_ROLLFWD;
cout << "\n Restoring a database ..." << endl;
cout << " - source image alias : " << db->getAlias() << endl;
cout << " - source image timestamp : " << restoreTimestamp << endl;
cout << " - target restored database: "
<< rolledForwardDb->getAlias() << endl;
// Restore database
db2Restore(db2Version1010, &restoreStruct, &sqlca);
DB2_API_CHECK("database restore -- start");
while (sqlca.sqlcode != 0)
{
// Continue the restore process
cout << "\n Continuing the restore operation..." << endl;
// Depending on the sqlca.sqlcode value,
// some user actions might be required like
// mounting a new tape, for example.
restoreStruct.iCallerAction = DB2RESTORE_CONTINUE;
// Restore the database
db2Restore(db2Version1010, &restoreStruct, &sqlca);
DB2_API_CHECK("database restore -- continue");
}
cout << "\n Restore finished." << endl;
// Start the rollforward process
cout << "\n Rolling forward '" << rolledForwardDb->getAlias()
<< "' database ..." << endl;
rfwdInput.iVersion = SQLUM_RFWD_VERSION;
rfwdInput.piDbAlias = rolledForwardDb->getAlias();
rfwdInput.iCallerAction = DB2ROLLFORWARD_RFWD_STOP;
rfwdInput.piStopTime = SQLUM_INFINITY_TIMESTAMP;
rfwdInput.piUserName = rolledForwardDb->getUser();
rfwdInput.piPassword = rolledForwardDb->getPswd();
rfwdInput.piOverflowLogPath = serverWorkingPath;
rfwdInput.iNumChngLgOvrflw = 0;
rfwdInput.piChngLogOvrflw = NULL;
rfwdInput.iConnectMode = DB2ROLLFORWARD_OFFLINE;
rfwdInput.piTablespaceList = NULL;
rfwdInput.iAllNodeFlag = DB2_ALL_NODES;
rfwdInput.iNumNodes = 0;
rfwdInput.piNodeList = NULL;
rfwdInput.piDroppedTblID = NULL;
rfwdInput.piExportDir = NULL;
rfwdInput.iNumNodeInfo = 1;
rfwdInput.iRollforwardFlags = DB2ROLLFORWARD_EMPTY_FLAG;
rfwdOutput.poApplicationId = rollforwardAppId;
rfwdOutput.poNumReplies = &numReplies;
rfwdOutput.poNodeInfo = &nodeInfo;
rfwdStruct.piRfwdInput = &rfwdInput;
rfwdStruct.poRfwdOutput = &rfwdOutput;
// Rollforward the database
db2Rollforward(db2Version1010, &rfwdStruct, &sqlca);
DB2_API_CHECK("rollforward -- start");
cout << " Rollforward finished." << endl;
// Drop the restored database
rc = DbDrop(rolledForwardDb->getAlias());
CHECKRC(rc, "DbDrop");
return 0;
} // DbRollfwd::DbBackupRestoreAndRollforward
int main(int argc, char *argv[])
{
int rc = 0;
CmdLineArgs check;
char serverWorkingPath[SQL_PATH_SZ + 1] = { 0 };
// sqluint16 savedLogRetainValue = 0;
char savedLogArchMeth1Value[252] = "\0";
Instance inst;
DbEmb db;
DbEmb rolledForwardDb;
DbRollFwd rollFwdRecov;
// Check the command line arguments
rc = check.CmdLineArgsCheck3(argc, argv, db, inst);
CHECKRC(rc, "check.CmdLineArgsCheck3");
rolledForwardDb.setDb("RFDB", db.getUser(), db.getPswd());
cout << "\nTHIS SAMPLE SHOWS HOW TO PERFORM ROLLFORWARD AFTER" << endl;
cout << "RESTORE OF A DATABASE" << endl;
// attach to a local or remote instance
rc = inst.Attach();
CHECKRC(rc, "inst.Attach");
// Get a server working path
rc = rollFwdRecov.ServerWorkingPathGet(&db, serverWorkingPath);
CHECKRC(rc, "rollFwdRecov.ServerWorkingPathGet");
cout << "\nNOTE: Backup images will be created on the server" << endl;
cout << " in the directory " << serverWorkingPath << "." << endl;
cout << " They will not be deleted by this program." << endl;
cout << "\n-----------------------------------------------------------";
cout << "\nUSE THE DB2 APIs:" << endl;
cout << " db2CfgGet -- GET CONFIGURATION" << endl;
cout << "TO GET THE CONFIGURATION OF A DATABASE." << endl;
// Save log retain value
rc = rollFwdRecov.DbLogArchMeth1ValueSave(&db, savedLogArchMeth1Value);
CHECKRC(rc, "rollFwdRecov.DbLogArchMeth1ValueSave");
// Call the sample functions
rc = rollFwdRecov.DbBackupRestoreAndRollforward(&db,
&rolledForwardDb,
serverWorkingPath);
CHECKRC(rc, "rollFwdRecov.DbBackupRestoreAndRollforward");
// Restore log retain value
rc = rollFwdRecov.DbLogArchMeth1ValueRestore(&db, savedLogArchMeth1Value);
CHECKRC(rc, "rollFwdRecov.DbLogArchMeth1ValueRestore");
// Detach from the local or remote instance
rc = inst.Detach();
CHECKRC(rc, "inst.Detach");
return 0;
} // main