Commit 50c91927 50c91927bb97dc82a9669fdf3920ad80f418914b by Christian Gerdes

Started implementing support for CDB/PDB handling. Experimental commit.

1 parent c3640d40
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"));
......