Started implementing support for CDB/PDB handling. Experimental commit.
Showing
1 changed file
with
62 additions
and
12 deletions
1 | package se.lil.om; | 1 | package se.lil.om; |
2 | 2 | ||
3 | import java.sql.*; | 3 | import java.sql.*; |
4 | import java.util.HashMap; | ||
5 | import java.util.Hashtable; | ||
4 | import java.util.Properties; | 6 | import java.util.Properties; |
5 | import java.util.concurrent.locks.Lock; | 7 | import java.util.concurrent.locks.Lock; |
6 | import java.util.concurrent.locks.ReentrantLock; | 8 | import java.util.concurrent.locks.ReentrantLock; |
... | @@ -12,6 +14,13 @@ public class OraMon { | ... | @@ -12,6 +14,13 @@ public class OraMon { |
12 | String conPass = "passw0rd"; | 14 | String conPass = "passw0rd"; |
13 | String dbName = null; | 15 | String dbName = null; |
14 | 16 | ||
17 | Boolean isPDB = false; | ||
18 | Boolean isCDB = false; | ||
19 | Boolean hasContainers = null; | ||
20 | OraMon containerDB = null; | ||
21 | |||
22 | private Hashtable<String, OraMon> myPDBs = null; | ||
23 | |||
15 | public static final int SYSSTAT = 1; | 24 | public static final int SYSSTAT = 1; |
16 | public static final int OSSTAT = 2; | 25 | public static final int OSSTAT = 2; |
17 | 26 | ||
... | @@ -37,6 +46,20 @@ public class OraMon { | ... | @@ -37,6 +46,20 @@ public class OraMon { |
37 | return this.conString; | 46 | return this.conString; |
38 | } | 47 | } |
39 | 48 | ||
49 | public String getServiceName() { | ||
50 | if(this.conString != null) { | ||
51 | int last = this.conString.lastIndexOf('/'); | ||
52 | if(last >=0) | ||
53 | return this.conString.substring(last +1); | ||
54 | else { | ||
55 | last = this.conString.lastIndexOf(':'); | ||
56 | return this.conString.substring(last +1); | ||
57 | } | ||
58 | } else { | ||
59 | return null; | ||
60 | } | ||
61 | } | ||
62 | |||
40 | //NUM_CPUS | 63 | //NUM_CPUS |
41 | int numCpus = 0; | 64 | int numCpus = 0; |
42 | public long getNumberOfCPUs() throws Throwable { | 65 | public long getNumberOfCPUs() throws Throwable { |
... | @@ -168,19 +191,27 @@ public class OraMon { | ... | @@ -168,19 +191,27 @@ public class OraMon { |
168 | } | 191 | } |
169 | 192 | ||
170 | long lastFetchTSns = 0; | 193 | long lastFetchTSns = 0; |
171 | public boolean getData(long ageTs) throws Throwable { | ||
172 | if ((System.nanoTime() - lastFetchTSns) > (ageTs * 1000 * 1000 * 1000)) return getData(); | ||
173 | else return false; | ||
174 | } | ||
175 | 194 | ||
176 | public long getAgeTs() { | 195 | public long getAgeTs() { |
177 | return (System.nanoTime() - lastFetchTSns)/(1000*1000*1000); | 196 | return (System.nanoTime() - lastFetchTSns)/(1000*1000*1000); |
178 | } | 197 | } |
179 | 198 | ||
199 | public boolean getData() throws Throwable { | ||
200 | return getData(0); | ||
201 | } | ||
202 | |||
180 | Lock lock = new ReentrantLock(); | 203 | Lock lock = new ReentrantLock(); |
181 | Throwable lastEx = null; | 204 | Throwable lastEx = null; |
182 | 205 | ||
183 | public boolean getData() throws Throwable { | 206 | public boolean getData(long ageTs) throws Throwable { |
207 | //Check age | ||
208 | if ((System.nanoTime() - lastFetchTSns) < (ageTs * 1000 * 1000 * 1000)) return false; | ||
209 | //Bail out if we are a PDB and ask the CDB OraMon object to update us | ||
210 | if(isPDB) { | ||
211 | if(containerDB != null) return containerDB.getData(ageTs); | ||
212 | // If we get here its strange. We know we are a PDB but we have no CDB object. | ||
213 | // Lets see if we ever end up here ;) | ||
214 | } | ||
184 | // Start thread safe | 215 | // Start thread safe |
185 | // Try to get a lock | 216 | // Try to get a lock |
186 | boolean haveLock = lock.tryLock(); | 217 | boolean haveLock = lock.tryLock(); |
... | @@ -213,7 +244,7 @@ public class OraMon { | ... | @@ -213,7 +244,7 @@ public class OraMon { |
213 | Statement stmt = conn.createStatement(); | 244 | Statement stmt = conn.createStatement(); |
214 | ResultSet rset = null; | 245 | ResultSet rset = null; |
215 | 246 | ||
216 | //Get the database name once | 247 | //Get the database name once // Currently always gets the CDB name |
217 | if(this.dbName == null) { | 248 | if(this.dbName == null) { |
218 | rset = stmt.executeQuery("select value from V$SYSTEM_PARAMETER where name = 'db_name'"); | 249 | rset = stmt.executeQuery("select value from V$SYSTEM_PARAMETER where name = 'db_name'"); |
219 | rset.next(); | 250 | rset.next(); |
... | @@ -221,24 +252,43 @@ public class OraMon { | ... | @@ -221,24 +252,43 @@ public class OraMon { |
221 | rset.close(); | 252 | rset.close(); |
222 | } | 253 | } |
223 | 254 | ||
255 | // Check if we can have containers | ||
256 | if(hasContainers == null) { | ||
257 | // We don't know, check if the CONTAINERS view exists in the database | ||
258 | rset = stmt.executeQuery("select count(*) from SYS.ALL_VIEWS where VIEW_NAME = 'V_$CONTAINERS'"); | ||
259 | if(rset.next()) { | ||
260 | if(rset.getInt(0) == 1) { | ||
261 | // We found the containers view. Enable container handling | ||
262 | hasContainers = true; | ||
263 | if(getServiceName().equals(this.dbName)) isCDB = true; | ||
264 | } | ||
265 | } | ||
266 | } | ||
267 | |||
268 | // If we have containers, but we are not the CDB, then we are a PDB. | ||
269 | // At this point we should close the connections, and ask the CDB OraMon object to getData() instead, and update us. | ||
270 | if(hasContainers && isCDB == false) { | ||
271 | |||
272 | } | ||
273 | |||
224 | //Get the entire V_$OSSTAT table from DB | 274 | //Get the entire V_$OSSTAT table from DB |
225 | colOsStat.update(stmt.executeQuery("select systimestamp, stat_name, value from V$OSSTAT")); | 275 | colOsStat.update(stmt.executeQuery("select systimestamp, stat_name, value from V$OSSTAT")); |
226 | 276 | ||
227 | //Set numCpus | 277 | //Set numCpus |
228 | this.numCpus = (int) colOsStat.getCurrentValue("NUM_CPUS"); | 278 | this.numCpus = (int) colOsStat.getCurrentValue("NUM_CPUS"); |
229 | 279 | ||
280 | // Get OS Load | ||
281 | osLoad.update(stmt.executeQuery("select systimestamp, value from V$OSSTAT where stat_name='LOAD'")); | ||
282 | |||
283 | |||
284 | // SYSSTAT and SYS_TIME_MODEL are specific for PDB and CDB/Instance is the total. | ||
285 | |||
230 | // Get DB CPU use time | 286 | // Get DB CPU use time |
231 | rset = stmt.executeQuery("select systimestamp, s.value as NIWT, t.value as DBCPU from V$SYSSTAT s, V$SYS_TIME_MODEL t where s.name='non-idle wait time' and t.STAT_NAME='DB CPU'"); | 287 | rset = stmt.executeQuery("select systimestamp, s.value as NIWT, t.value as DBCPU from V$SYSSTAT s, V$SYS_TIME_MODEL t where s.name='non-idle wait time' and t.STAT_NAME='DB CPU'"); |
232 | rset.next(); | 288 | rset.next(); |
233 | niwTime.update(rset.getLong(2), rset.getTimestamp(1)); | 289 | niwTime.update(rset.getLong(2), rset.getTimestamp(1)); |
234 | cpuTime.update(rset.getLong(3), rset.getTimestamp(1)); | 290 | cpuTime.update(rset.getLong(3), rset.getTimestamp(1)); |
235 | rset.close(); | 291 | rset.close(); |
236 | |||
237 | // cpuTime.update(stmt.executeQuery("select systimestamp, value from V$SYS_TIME_MODEL where stat_name='DB CPU'")); | ||
238 | // niwTime.update(stmt.executeQuery("select systimestamp, value from V$SYSSTAT where name='non-idle wait time'")); | ||
239 | |||
240 | // Get OS Load | ||
241 | osLoad.update(stmt.executeQuery("select systimestamp, value from V$OSSTAT where stat_name='LOAD'")); | ||
242 | 292 | ||
243 | //Get the entire V_$SYSSTAT table from DB | 293 | //Get the entire V_$SYSSTAT table from DB |
244 | colSysStat.update(stmt.executeQuery("select systimestamp, name, value from V$SYSSTAT")); | 294 | colSysStat.update(stmt.executeQuery("select systimestamp, name, value from V$SYSSTAT")); | ... | ... |
-
Please register or sign in to post a comment