1 21 22 package org.continuent.sequoia.controller.backup.backupers; 23 24 import java.io.File ; 25 import java.io.IOException ; 26 import java.util.ArrayList ; 27 import java.util.Date ; 28 29 import org.continuent.sequoia.common.exceptions.BackupException; 30 import org.continuent.sequoia.common.log.Trace; 31 import org.continuent.sequoia.controller.backend.DatabaseBackend; 32 import org.continuent.sequoia.controller.backup.BackupManager; 33 import org.continuent.sequoia.controller.backup.DumpTransferInfo; 34 35 52 public class PostgreSQLBinaryBackuper extends AbstractPostgreSQLBackuper 53 { 54 static Trace logger = Trace 56 .getLogger(PostgreSQLBinaryBackuper.class 57 .getName()); 58 59 62 public static final String DUMP_FORMAT = "PostgreSQL Binary Dump"; 63 64 67 public String getDumpFormat() 68 { 69 return DUMP_FORMAT; 70 } 71 72 76 public Date backup(DatabaseBackend backend, String login, String password, 77 String dumpName, String path, ArrayList tables) throws BackupException 78 { 79 String url = backend.getURL(); 81 PostgreSQLUrlInfo info = new AbstractPostgreSQLBackuper.PostgreSQLUrlInfo( 82 url); 83 84 if (logger.isDebugEnabled()) 85 logger.debug("Backing up database '" + info.getDbName() + "' on host '" 86 + info.getHost() + ":" + info.getPort() + "'"); 87 88 try 89 { 90 File pathDir = new File (path); 92 if (!pathDir.exists()) 93 { 94 pathDir.mkdirs(); 95 pathDir.mkdir(); 96 } 97 String fullPath = getDumpPhysicalPath(path, dumpName); 98 99 boolean succeeded = false; 100 String dumpOptions = ""; 101 if (pgDumpFlags != null) 102 { 103 if (pgDumpFlags.indexOf("-F") >= 0 104 || pgDumpFlags.indexOf("--format=") >= 0) 105 { 106 logger.error("Invalid option in pgDumpFlags \"" + pgDumpFlags 107 + "\". You are not allowed to set the format of the dump!"); 108 } 109 else 110 { 111 dumpOptions = " " + pgDumpFlags + " "; 112 } 113 } 114 if (useAuthentication) 115 { 116 if (logger.isDebugEnabled()) 118 logger.debug("Performing backup using authentication"); 119 int timeout = -1; 120 if (dumpTimeout != null) 121 { 122 try 123 { 124 timeout = Integer.parseInt(dumpTimeout); 125 } 126 catch (NumberFormatException e) 127 { 128 logger.error("\"" + dumpTimeout 129 + "\" is not a valid dump-timeout value!"); 130 timeout = -1; 131 } 132 } 133 String [] expectFeed = makeExpectDialogueWithAuthentication("pg_dump", 134 info, " --format=c -f " + fullPath + dumpOptions, login, password, 135 timeout); 136 137 String [] cmd = makeExpectCommandReadingStdin(); 138 139 succeeded = safelyExecNativeCommand(cmd, expectFeed, 0); 140 } 141 else 142 { 143 if (pgDumpFlags != null) 144 { 145 if (pgDumpFlags.indexOf("-U") >= 0 || pgDumpFlags.indexOf("-W") >= 0) 146 { 147 logger 148 .error("Invalid option in pgDumpFlags \"" 149 + pgDumpFlags 150 + "\". Set \"authentication=true\" if you want to use authentication!"); 151 } 152 else 153 { 154 dumpOptions = " " + pgDumpFlags + " "; 155 } 156 } 157 158 String cmd = makeCommand("pg_dump", info, " --format=c -f " + fullPath 159 + dumpOptions, login); 160 succeeded = safelyExecNativeCommand(cmd, null, 0); 161 } 162 163 if (! succeeded) 164 { 165 throw new BackupException( 166 "pg_dump execution did not complete successfully!"); 167 } 168 169 } 170 catch (Exception e) 171 { 172 String msg = "Error while performing backup"; 173 logger.error(msg, e); 174 throw new BackupException(msg, e); 175 } 176 177 return new Date (System.currentTimeMillis()); 178 } 179 180 184 public void restore(DatabaseBackend backend, String login, String password, 185 String dumpName, String path, ArrayList tables) throws BackupException 186 { 187 String url = backend.getURL(); 189 PostgreSQLUrlInfo info = new AbstractPostgreSQLBackuper.PostgreSQLUrlInfo( 190 url); 191 192 if (logger.isDebugEnabled()) 193 logger.debug("Restoring database '" + info.getDbName() + "' on host '" 194 + info.getHost() + ":" + info.getPort() + "'"); 195 196 String fullPath = getDumpPhysicalPath(path, dumpName); 198 File dump = new File (fullPath); 199 if (!dump.exists()) 200 throw new BackupException("Backup '" + fullPath + "' does not exist!"); 201 202 try 203 { 204 if (useAuthentication) 205 { 206 if (logger.isInfoEnabled()) 207 logger.info("Performing database operations using authentication"); 208 209 if (logger.isDebugEnabled()) 211 logger.debug("Dropping database '" + info.getDbName() + "'"); 212 213 String [] expectFeed = makeExpectDialogueWithAuthentication("dropdb", 214 info, "", login, password, 60); 216 String [] cmd = makeExpectCommandReadingStdin(); 217 218 if (! safelyExecNativeCommand(cmd, expectFeed, 0)) 219 { 220 logger.warn("Unable to drop drop database prior to restore"); 221 } 222 223 if (logger.isDebugEnabled()) 225 logger.debug("Re-creating '" + info.getDbName() + "'"); 226 227 expectFeed = makeExpectDialogueWithAuthentication("createdb", info, 228 encoding != null ? "--encoding=" + encoding + " " : "", login, 229 password, 60); 231 cmd = makeExpectCommandReadingStdin(); 232 233 if (! safelyExecNativeCommand(cmd, expectFeed, 0)) 234 { 235 throw new BackupException( 236 "createdb execution did not complete successfully!"); 237 } 238 239 if (preRestoreScript != null) 241 { 242 if (logger.isDebugEnabled()) 243 logger.debug("Running pre-restore script '" + preRestoreScript 244 + "' on '" + info.getDbName() + "'"); 245 246 expectFeed = makeExpectDialogueWithAuthentication("psql", info, 247 "--pset pager -f " + preRestoreScript, login, password, 300); 251 cmd = makeExpectCommandReadingStdin(); 252 253 if (! safelyExecNativeCommand(expectFeed, cmd, 0)) 254 { 255 throw new BackupException( 256 "psql execution did not complete successfully!"); 257 } 258 } 259 260 if (logger.isDebugEnabled()) 262 logger.debug("Rebuilding '" + info.getDbName() + "' from dump '" 263 + dumpName + "'"); 264 265 int timeout = -1; 266 if (restoreTimeout != null) 267 { 268 try 269 { 270 timeout = Integer.parseInt(restoreTimeout); 271 } 272 catch (NumberFormatException e) 273 { 274 logger.error("\"" + restoreTimeout 275 + "\" is not a valid restore-timeout value!"); 276 timeout = -1; 277 } 278 } 279 280 expectFeed = makeExpectDialogueWithAuthentication("pg_restore", info, 281 "--format=c -d " + info.getDbName() + " " + fullPath, login, 282 password, timeout); 284 cmd = makeExpectCommandReadingStdin(); 285 286 if (! safelyExecNativeCommand(cmd, expectFeed, 0)) 287 { 288 throw new BackupException( 289 "pg_restore execution did not complete successfully!"); 290 } 291 292 if (postRestoreScript != null) 294 { 295 if (logger.isDebugEnabled()) 296 logger.debug("Running post-restore script '" + postRestoreScript 297 + "' on '" + info.getDbName() + "'"); 298 299 expectFeed = makeExpectDialogueWithAuthentication("psql", info, 300 "--pset pager -f " + postRestoreScript, login, password, 300); 304 cmd = makeExpectCommandReadingStdin(); 305 306 if (! safelyExecNativeCommand(expectFeed, cmd, 0)) 307 { 308 throw new BackupException( 309 "psql execution did not complete successfully!"); 310 } 311 } 312 } 313 else 314 { 316 if (logger.isDebugEnabled()) 318 logger.debug("Dropping database '" + info.getDbName() + "'"); 319 320 String dropCmd = makeCommand("dropdb", info, "", login); 321 if (! safelyExecNativeCommand(dropCmd, null, 0)) 322 { 323 logger.warn("Unable to drop drop database prior to restore"); 326 } 327 328 if (logger.isDebugEnabled()) 330 logger.debug("Re-creating '" + info.getDbName() + "'"); 331 332 String createCmd = makeCommand("createdb", info, encoding != null 333 ? "--encoding=" + encoding + " " 334 : "", login); 335 if (! safelyExecNativeCommand(createCmd, null, 0)) 336 { 337 throw new BackupException( 338 "createdb execution did not complete successfully!"); 339 } 340 341 if (preRestoreScript != null) 343 { 344 if (logger.isDebugEnabled()) 345 logger.debug("Running pre-restore script '" + preRestoreScript 346 + "' on '" + info.getDbName() + "'"); 347 348 String preRestoreCmd = makeCommand("psql", info, "--pset pager -f " 349 + preRestoreScript, login); 350 if (! safelyExecNativeCommand(preRestoreCmd, null, 0)) 351 { 352 printErrors(); 353 throw new BackupException( 354 "psql execution did not complete successfully!"); 355 } 356 } 357 358 if (logger.isDebugEnabled()) 360 logger.debug("Rebuilding '" + info.getDbName() + "' from dump '" 361 + dumpName + "'"); 362 363 String replayCmd = makeCommand("pg_restore", info, "--format=c -d " 364 + info.getDbName() + " " + fullPath, login); 365 if (! safelyExecNativeCommand(replayCmd, null, 0)) 366 { 367 throw new BackupException( 368 "pg_restore execution did not complete successfully!"); 369 } 370 371 if (postRestoreScript != null) 373 { 374 if (logger.isDebugEnabled()) 375 logger.debug("Running post-restore script '" + postRestoreScript 376 + "' on '" + info.getDbName() + "'"); 377 378 String postRestoreCmd = makeCommand("psql", info, "--pset pager -f " 379 + postRestoreScript, login); 380 if (! safelyExecNativeCommand(postRestoreCmd, null, 0)) 381 { 382 throw new BackupException( 383 "psql execution did not complete successfully!"); 384 } 385 } 386 } 387 } 388 catch (Exception e) 389 { 390 String msg = "Error while performing backup"; 391 logger.error(msg, e); 392 throw new BackupException(msg, e); 393 } 394 } 395 396 400 public void fetchDump(DumpTransferInfo dumpTransferInfo, String path, 401 String dumpName) throws BackupException, IOException  402 { 403 BackupManager.fetchDumpFile(dumpTransferInfo, path, dumpName); 404 } 405 } 406 | Popular Tags |