KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > continuent > sequoia > controller > backup > backupers > MySQLTarBackuper


1 /**
2  * Sequoia: Database clustering technology.
3  * Copyright (C) 2006 Continuent, Inc.
4  * Contact: sequoia@continuent.org
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * Initial developer(s): Emmanuel Cecchet.
19  * Contributor(s): ______________________.
20  */

21
22 package org.continuent.sequoia.controller.backup.backupers;
23
24 import java.io.File JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Date JavaDoc;
27 import java.util.regex.Matcher JavaDoc;
28 import java.util.regex.Pattern JavaDoc;
29
30 import org.continuent.sequoia.common.exceptions.BackupException;
31 import org.continuent.sequoia.controller.backend.DatabaseBackend;
32
33 /**
34  * This class defines a MySQLTarBackuper to backup a MySQL database (usually
35  * MyIsam) contained in a single directory. This is based on the TarBackuper.
36  * <p>
37  * Options for this backuper are (datadir is the only mandatory option):
38  *
39  * <pre>
40  * - bindir: path to the 'tar' command (if not in classpath)
41  * - mysqlbindir: path to the 'mysqladmin' command (to drop the database before restoring)
42  * - datadir: path to the data directory where dbs can be found (we expect the
43  * directory to be named after the virtual database name). For example, if
44  * datadir=/var/lib/mysql/data we expect the virtual database db1 data to be
45  * found in /var/lib/mysql/data/db1
46  * - dumpServer: address to bind the dump server
47  * </pre>
48  *
49  * Configuration example:
50  * <p>
51  * <Backuper backuperName="mysqltar"
52  * className="org.continuent.sequoia.controller.backup.backupers.MySQLTarBackuper"
53  * options="datadir=/var/lib/mysql/data"/>
54  * <p>
55  * Caveat: Sequoia must have access in read/write to the directory to
56  * backup/restore. The less intrusive way is to execute Sequoia as the mysql
57  * user. The other way, it that the user executing Sequoia belongs to the mysql
58  * group and that the mysql data directory is open in read/write to the mysql
59  * group.
60  *
61  * @author <a HREF="mailto:emmanuel.cecchet@continuent.com">Emmanuel Cecchet</a>
62  * @version 1.0
63  */

64 public class MySQLTarBackuper extends TarBackuper
65 {
66   private static final String JavaDoc DEFAULT_MYSQL_PORT = "3306";
67
68   private static final String JavaDoc DEFAULT_MYSQL_HOST = "localhost";
69
70   /**
71    * @see org.continuent.sequoia.controller.backup.Backuper#getDumpFormat()
72    */

73   public String JavaDoc getDumpFormat()
74   {
75     return "MySQL tar dump";
76   }
77
78   /**
79    * @see org.continuent.sequoia.controller.backup.backupers.TarBackuper#backup(org.continuent.sequoia.controller.backend.DatabaseBackend,
80    * java.lang.String, java.lang.String, java.lang.String,
81    * java.lang.String, java.util.ArrayList)
82    */

83   public Date JavaDoc backup(DatabaseBackend backend, String JavaDoc login, String JavaDoc password,
84       String JavaDoc dumpName, String JavaDoc path, ArrayList JavaDoc tables) throws BackupException
85   {
86     String JavaDoc url = backend.getURL();
87     if (!url.startsWith("jdbc:mysql:"))
88     {
89       throw new BackupException("Unsupported db url " + url);
90     }
91     return super.backup(backend, login, password, dumpName, path, tables);
92   }
93
94   /**
95    * @see org.continuent.sequoia.controller.backup.backupers.TarBackuper#restore(org.continuent.sequoia.controller.backend.DatabaseBackend,
96    * java.lang.String, java.lang.String, java.lang.String,
97    * java.lang.String, java.util.ArrayList)
98    */

99   public void restore(DatabaseBackend backend, String JavaDoc login, String JavaDoc password,
100       String JavaDoc dumpName, String JavaDoc path, ArrayList JavaDoc tables) throws BackupException
101   {
102     String JavaDoc url = backend.getURL();
103     if (!url.startsWith("jdbc:mysql:"))
104     {
105       throw new BackupException("Unsupported db url " + url);
106     }
107     MySQLUrlInfo info = new MySQLUrlInfo(url);
108
109     // Drop the database if it already exists
110
if (logger.isDebugEnabled())
111       logger.debug("Dropping database '" + info.getDbName() + "'");
112
113     String JavaDoc mysqladminExecutablePath = (optionsMap.containsKey("mysqlbindir")
114         ? (String JavaDoc) optionsMap.get("mysqlbindir") + File.separator
115         : "")
116         + "mysqladmin";
117     try
118     {
119       if (nativeCmdExec.executeNativeCommand(mysqladminExecutablePath + " -h "
120           + info.getHost() + " --port=" + info.getPort() + " -f -u" + login
121           + " --password=" + password + " drop " + info.getDbName(), null,
122           null, 0, getIgnoreStdErrOutput()) != 0)
123       {
124         // Errors can happen there, e.g. if the database does not exist yet.
125
// Just log them, and carry-on...
126
printErrors();
127       }
128     }
129     catch (Exception JavaDoc e)
130     {
131       logger.error("Failed to drop database (tar command may fail afterwards)",
132           e);
133     }
134
135     super.restore(backend, login, password, dumpName, path, tables);
136   }
137
138   /**
139    * Allow to parse MySQL URL.
140    */

141   protected class MySQLUrlInfo
142   {
143     private boolean isLocal;
144
145     private String JavaDoc host;
146
147     private String JavaDoc port;
148
149     private String JavaDoc dbName;
150
151     // Used to parse url
152
private Pattern JavaDoc pattern = Pattern
153                                 .compile("jdbc:mysql:((//([a-zA-Z0-9_\\-.]+|\\[[a-fA-F0-9:]+])((:(\\d+))|))/|)([a-zA-Z][a-zA-Z0-9_\\-]*)(\\?.*)?");
154
155     Matcher JavaDoc matcher;
156
157     /**
158      * Creates a new <code>MySQLUrlInfo</code> object, used to parse the
159      * postgresql jdbc options. If host and/or port aren't specified, will
160      * default to localhost:3306. Note that database name must be specified.
161      *
162      * @param url the MySQL JDBC url to parse
163      */

164     public MySQLUrlInfo(String JavaDoc url)
165     {
166       matcher = pattern.matcher(url);
167
168       if (matcher.matches())
169       {
170         if (matcher.group(3) != null)
171           host = matcher.group(3);
172         else
173           host = DEFAULT_MYSQL_HOST;
174
175         if (matcher.group(6) != null)
176           port = matcher.group(6);
177         else
178           port = DEFAULT_MYSQL_PORT;
179
180         dbName = matcher.group(7);
181       }
182     }
183
184     /**
185      * Gets the HostParameters of this postgresql jdbc url as a String that can
186      * be used to pass into cmd line/shell calls.
187      *
188      * @return a string that can be used to pass into a cmd line/shell call.
189      */

190     public String JavaDoc getHostParametersString()
191     {
192       if (isLocal)
193       {
194         return "";
195       }
196       else
197       {
198         return "-h " + host + " --port=" + port;
199       }
200     }
201
202     /**
203      * Gets the database name part of this postgresql jdbc url.
204      *
205      * @return the database name part of this postgresql jdbc url.
206      */

207     public String JavaDoc getDbName()
208     {
209       return dbName;
210     }
211
212     /**
213      * Gets the host part of this postgresql jdbc url.
214      *
215      * @return the host part of this postgresql jdbc url.
216      */

217     public String JavaDoc getHost()
218     {
219       return host;
220     }
221
222     /**
223      * Gets the port part of this postgresql jdbc url.
224      *
225      * @return the port part of this postgresql jdbc url.
226      */

227     public String JavaDoc getPort()
228     {
229       return port;
230     }
231
232     /**
233      * Checks whether this postgresql jdbc url refers to a local db or not, i.e.
234      * has no host specified, e.g. jdbc:postgresql:myDb.
235      *
236      * @return true if this postgresql jdbc url has no host specified, i.e.
237      * refers to a local db.
238      */

239     public boolean isLocal()
240     {
241       return isLocal;
242     }
243
244   }
245
246 }
247
Popular Tags