TimesTen Auditing Using ttAudit.java Installation, Operation, and Configuration As of: TimesTen 220.127.116.11, September, 2013 The ttAudit.java application is free, open source project software that is provided as a convenience to the customer without a warranty of any kind and without support. Licensing terms are here: https://oss.oracle.com/licenses/CDDL Unlike the Oracle database, the Oracle TimesTen in-memory database does not have built-in auditing features. However, using TimesTen’s event notification API, JMS/XLA (documented in the TimesTen Java User’s Guide), an application called ttAudit.java has been developed to provide very detailed auditing. Information about all transactions that modify the database or update the data can be audited and saved. Normally, audit information is stored in an Oracle database, but it can be stored in a TimesTen database or in a flat file in the file system. As TimesTen supports very high write transaction throughput, a very large amount of audit data could be generated. The following events can be audited: INSERT, UPDATE, DELETE, all DDL (e.g. DROP TABLE, CREATE TABLE, ALTER TABLE), and materialized view updates. For INSERT, all columns that are inserted into the table can be saved if the –fullInsertAudit option is used on the command line. For UPDATEs, the old value and new value of the columns are saved. For DELETE, the values of the columns in the primary key or unique index of the tables of the deleted row are saved. The following events cannot be audited, as they are not logged in TimesTen’s logging system: SELECT, TRUNCATE TABLE, and operations to Temporary Tables. Note that JMS/XLA is an asynchronous API. The timestamp of the transaction will be the time that JMS/XLA read the transaction on the log file, unless the updated table has a timestamp column that is updated upon every UPDATE. At this point, we recommend that you go through the tutorial in the next section. Getting Started Tutorial The sample session assumes that you installed the Quickstart when you installed the Oracle TimesTen software. It is also assumed that you know a few of the basics of the TimesTen database. . If you do not have an Oracle database, you can output ttAudit auditing information to a flat file. If you do wish to store auditing information to an Oracle database, it is also assumed that you have access to an Oracle database, 10.2.0.4 or later, you have permissions to create users and tables on it, and that you understand TNSNAMES connections. You must have an Oracle Sun Java Development Kit (JDK) installed as well. If you are not familiar with TimesTen, see: http://download.oracle.com/otn_hosted_doc/timesten/1122/quickstart/html/admin/db_ops.html 1) This tutorial assumes that you have installed TimesTen 11.2.2.x and a 64-bit Sun Java Development Kit (JDK) 1.6 or higher on 64-bit Linux. It is also assumed that you have a basic understanding of TimesTen. 2) Set an environment variable called $TT_HOME that points to the installation directory of TimesTen, e.g. export TT_HOME=/opt/TimesTen/tt1122 Also verify that your PATH environment variable is set to the TimesTen bin directory: export PATH=$TT_HOME/bin:$PATH 3) Open terminal windows on your Linux system. If you are on a GUI Linux workstation such as KDE or Gnome, at the menu at the top of the screen, select Applications -> Accessories -> Terminal. 4) Download the most recent ttAudit.jar file at : http://java.net/projects/ttaudit/downloads You can do this with a browser like Firefox. (On the Linux GUI screen, select Applications -> Internet -> Firefox (or whatever browser is available). Go to the URL http://java.net/projects/ttaudit/downloads . Select Save File. 5) Open a Linux terminal window. Find the place where you saved the ttAudit.jar file. Copy it to a directory of your choice. Extract the jar file with: cd [directory of your choice] jar xvf ttAudit.jar cp src/scripts/* $PWD cp src/sql/* $PWD cp src/*xml $PWD 6) For this tutorial, we will use two TimesTen data stores, one for transactions, and one for storing audit information. In a production system, however, it is recommended than an Oracle database is used for audit information, as this data will quickly grow to a size larger than available memory. The next tutorial section uses an Oracle database. 7) cd $TT_HOME/info . Edit the sys.odbc.ini file. Notice that there is already a data store DSN defined in this file called [sampledb_1122] (or, depending on the TimesTen version you have installed, it could be sampledb_VERSION. Do NOT select ampledbCS_1122.) We will use this DSN as the data store for transactions. Make sure you have the following in your sys.odbc.ini file. Note that the directory names in Driver and DataStore should probably not be changed. [sampledb_1122] Driver=/TIMESTEN_DIRECTORY/lib/libtten.so DataStore=/a_writable_directory /sampledb_1122 PermSize=40 TempSize=32 PLSQL=1 DatabaseCharacterSet=US7ASCII 8) We will now create another data store called sampleaudit_1122, with a client connection called sampleauditCS_1122. Copy the lines of sampledb_1122 in this file, then edit the file to make the following changes (in BOLD): [sampleaudit_1122] Driver=/writable_directory/libtten.so DataStore=/writable_directory /sampleaudit_1122 PermSize=100 TempSize=32 PLSQL=1 DatabaseCharacterSet=US7ASCII [sampleauditCS_1122] TTC_SERVER=localhost TTC_SERVER_DSN=sampleaudit_1122 You should now have two data stores defined in sys.odbc.ini, sampledb_1122 and sampleaudit_1122. Save changes to the file and exit. 9) Destroy any sampledb_1122 database that exists with: ttDestroy sampledb_1122 Ignore any “data store not exists” error. 10) cd $TT_HOME/quickstart/sample_scripts/createdb . Edit the file build_sampledb.sh; make sure that the data store name referenced throughout is sampledb_1122 (not sampledb_1121 or something else.) 11) Run ./build_sampledb.sh . When prompted for an “adm” password, enter adm. When prompted for “appuser”, enter appuser. When prompted for “xlauser”, enter xlauser . 12) cd to your chosen ttAudit directory. Enter: ttIsql sampledb_1122 . As you are logged in as the instance administrator, and you did not specify a UID on the connection string, you are now logged in as the TimesTen superuser / instance administrator. Enter this command: grant all to xlauser; 13) Enter these commands in ttIsql: disconnect; connect “dsn=sampledb_1122;uid=xlauser;pwd=xlauser”; 14) For this tutorial, we will be saving auditing information to another TimesTen data store. (NOTE: If you wish to store auditing information in an Oracle database, you need to change the settings in the file runAuditDemo.sh. Note the section of this file “Oracle database for holding ttAudit data”. ) In another terminal session, cd to your chosen ttAudit directory, and edit the file runAuditDemo.sh . Change the value of TTJAVA_HOME to the directory where the bin directory of your Oracle Sun JDK resides. It is important that the “java” command run an Oracle Sun JVM and not the open source JVM that is shipped with Linux. If you do not know where the Oracle Sun JDK is installed, this command may help: find / -name javac -print 15) Again editing runAuditDemo.sh, verify that the following environment variables are set as below: export TTAUDIT_HOME=your_chosen_ttAudit_directory export TTJAVA_HOME=path_to_your_Sun_JDK_directory export TTAUDIT_XLAURL="jdbc:timesten:direct:sampledb_1122" export TTAUDIT_XLADRIVER="com.timesten.jdbc.TimesTenDriver" export TTAUDIT_XLAUID="ttaudit" export TTAUDIT_XLAPWD="timesten" export TTAUDIT_DBURL="jdbc:timesten:client:sampleauditCS_1122" export TTAUDIT_DBDRIVER="com.timesten.jdbc.TimesTenDriver" export TTAUDIT_DBUID="ttaudit" export TTAUDIT_DBPWD="timesten" Save changes and exit. 16) Edit the file jmsxla.xml . In the ConnectionString under the “audit” topic, verify that the line connectionString = “DSN=sampledb_1122” . Save and exit. 17) Connect to TimesTen as below and enter the below command: ttIsql –connStr “dsn=sampledb_1122;uid=xlauser;pwd=xlauser” Command> @auditTablesDDLTimesTen.sql; Command> exit; You have now created the tables necessary for auditing. 18) We will now set up the data store to hold auditing information. ttIsql –connStr “dsn=sampleaudit_1122” Command> @auditTablesDDLTimesTen.sql; Command> exit; Note: if you are using the Oracle database to store audit data, use the script auditTablesDDLauditDB.sql . 19) Run this command, and leave it running. cd to your chosen ttAudit directory chmod 755 runAuditDemo.sh ./runAuditDemo.sh Every 5 seconds, you will see a “got a UPDATE” message. ttAudit updates a table called auditmonitor every 5 seconds to make sure the XLA bookmark is advancing. 20) In another terminal session, enter these commands: ttIsql –connStr “dsn=sampledb_1122;uid=ttaudit;pwd=timesten” Command> autocommit 0; Command> insert into appuser.mytable values(‘Test0’,0); Command> commit; 21) On the other terminal session from #19 above, you should now see several messages. Try updating the row you just inserted in ttIsql: Command> update appuser.mytable set i = 10; Command> commit; Notice that on your other terminal there are messages indicating that the table has been updated. Note that the messages do not appear until you COMMIT the transaction. 22) In the same ttIsql session: call ttLogHolds; update appuser.mytable set i = 11; commit; call ttLogHolds; Did you notice how the XLA bookmark’s log hold ID (the number in the second column of the result set of ttLogHolds) is bigger the second time you called ttLogHolds? This means that the XLA bookmark is advancing, which is what you want to see. 23) You can create a new table, and it will automatically be picked up by the auditing program. Try this in ttIsql: create table newtable (uuid_pk binary(4) not null primary key, update_user varchar(20)); Note that DDL is autocommited as it is in the Oracle database. Notice that the auditing application re-starts. insert into newtable values(0x0123, ’AUDITOR’); commit; 24) Now in another terminal session, let’s connect to the other TimesTen data store and run a report of the transactions that were audited: ttIsql –connStr “dsn=sampleaudit_1122;uid=ttaudit;pwd=timesten” Command> @auditQuery01.sql; ( NOTE: If you are using an Oracle database to store audit information, do the following: sqlplus ttaudit/timesten SQL> @auditQuery01Oracle.sql; ) You will note that the fact that you issued a CREATE TABLE statement is shown 4 rows from the bottom of the result set. Note the last two rows of the result set: DB TRX NUM: TRX PART NUM: USER: DATE/TIME: TRX_TYPE: TABLE: PRIMARYKEY? COLUMN: OLD VALUE: NEW VALUE: 192093093.332 19 AUDITOR 22-JUL-13 10.34.09.589000 PM INSERT XLAUSER.NEWTABLE Y UUID_PK DB TRX NUM: TRX PART NUM: USER: DATE/TIME: TRX_TYPE: TABLE: PRIMARYKEY? COLUMN: OLD VALUE: NEW VALUE: 192093093.332 19 AUDITOR 22-JUL-13 10.34.09.589000 PM INSERT XLAUSER.NEWTABLE Y UPDATE_USER 01230000 AUDITOR The first number is the TimesTen transaction ID. A new transaction ID is generated every time COMMIT is called. The user who executed the transaction was AUDITOR. The transaction was executed at the date and time shown. It was an INSERT (not an UPDATE or DELETE) on the table XLAUSER.NEWTABLE. The first column inserted, ID, is a primary key on the table as indicated with “Y”. The old column value is null, as this was an INSERT. (If it were an UPDATE, instead of NULL, you would see the old value of the column before the update.) The value inserted was 0123000 (converted from RAW to VARCHAR2) for UUID_PK, and as shown on the next row of the result set, the value inserted for UPDATE_USER was AUDITOR. (NOTE: If you are running with the Oracle database as your audit database, you can now run a query where we get specific values of UUID_PK: SQL> @auditQueryOracleUUID In another terminal session, you can edit the file auditQueryOracleUUID.sql. Look at the select statement and see how the query is performed.) 25) Now let’s try to drop the table you just created. In the ttIsql session, do: Command> drop table newtable; 8068: Cannot drop a table or view that is subscribed to by an XLA bookmark. Command> update ttAudit.auditTables set auditEnabled = ’N’ where fullTableName = ’XLAUSER.NEWTABLE’; Give the ttAudit program a few seconds to re-start. Command> drop table newtable; 26) You may abort the auditing program now if you wish. Go to the terminal session where it is running and press CTRL-C. This program detects signals and shuts down properly. NOTE: if you ever wish to kill the process using the Linux “kill” command, please use “kill” or “kill -3”, NOT “kill -9”. Installation and Configuration Notes Enabling Auditing: To enable auditing in a TimesTen database, simply run the DDL script auditTablesDDLTimesTen.sql with a tool like SQLDeveloper or ttIsql , as we did in step 13 of the tutorial in this document. Edit the .sh script that runs ttAudit (see the tutorial), edit the jmsxla.xml file and change the value of “Connection String” to your DSN (see the tutorial), then launch ttAudit. When ttAudit first runs, it will scan the metadata in TimesTen for all of the non-system tables and automatically enable auditing for all of these tables. By default, any new table or materialized view will automatically be picked up by ttAudit and audited. (If you do not want new tables audited, specify the –ignoreDDL command line option for ttAudit.) Make sure the jmsxla.xml file is in the directory where you are running ttAudit, making sure that the “audit” topic has the correct DSN defined for the database that you wish to audit. Monitoring Auditing and Bookmarks: JMS/XLA uses a bookmark on the TimesTen logging system. Normally, XLA can read the log data of events off the in-memory log buffer. Oracle recommends setting both LogBufMB and LogFileSize in sys.odbc.ini to the same value, and that value should be 1024. If the log buffer fills up, the bookmark can also be placed on the log file(s) on disk. The bookmark must constantly be advancing. If the bookmark does not advance, log files will not be purged when a TimesTen checkpoint occurs. This will cause log files to accumulate until you run out of disk space. ttAudit constantly updates the ttaudit.auditmontor table (you will note that the timestamp column, ts, is updated every 5 seconds) and advances the bookmark when this update takes place. You can also call the “call ttLogHolds” function in TimesTen in ttIsql or SqlDeveloper. The XLA bookmark(s) are listed. The number on the left of the result set should be advancing every few seconds. You must make sure that ttAudit is running at all times, so the bookmark is constantly advancing. Customers typically have a shell script that is called through “cron” every few minutes to make sure that ttAudit is running. Using the Oracle Database To Store Audit Data: You need to edit the auditTablesDDLauditDB.sql script and run it with DBA permissions. Add your own information about tablespaces to this script as appropriate. You will notice that several tables are created, including ttAudit, ttAuditDetail, and ttAuditColumns. The ttAuditColumns table could contain a very large number of rows. A row is inserted into ttAudit for every transaction COMMIT. One or more rows are inserted into ttAuditDetail for each part of the transaction; for example, if the transaction consists of 3 inserts and 1 delete, there will be 4 rows in ttAuditDetail for this transaction. Each of the columns that were updated, and the values of the columns that are part of the primary key (or unique index) are stored in the ttAuditColumns table. The auditQuery02Oracle.sql script demonstrates how the tables are joined, and how data can be queried from these tables. Once the auditTablesDDLauditDB.sql script has been run in the Oracle database, edit one of the rumAudit.sh scripts provided; make sure that TTAUDIT_DBURL, TTAUDIT_DBDRIVER, TT_AUDIT_DBUID, and TTAUDIT_DBPWD are set appropriately. The UID and PWD must have permission in the Oracle database to read and write to the tables in the ttAudit schema. Disabling Auditing: To disable auditing and remove the bookmark, make sure the ttAudit application is running, then issue this SQL statement in the database you are auditing with a tool like ttIsql or SqlDeveloper: update ttaudit.auditmonitor set auditEnabled = ‘N’; commit; The ttAudit application will automatically unsubscribe all of the tables, remove the bookmark, and shut down. If you wish to re-enable auditing, update the above column to ‘Y’. Storing Auditing Data As a File In The File System: Rather than storing auditing data in a database, you can save it to a flat file in the file system. (The file has comma (,) delimiters by default, but that can be changed on the command line.) Specify -outfile “/fullPathTo/filename” on the ttAudit command line; this will write audit data to the flat file and not connect to any database for storing audit data. A script called externalTableDDL.sql is provided that provides a full description of the file and instructions on how to load it into an Oracle database as an External Table. Installing ttAudit With TimesTen-to-TimesTen Replication: ttAudit works with TimesTen ACTIVE STANDBY PAIR replication. (Please refer to the TimesTen Replication Guide if you are not familiar with TimesTen replication.) If you wish to run ttAudit on a read-only subscriber, please skip to the section “Running ttAudit on a TimesTen Replication STANDBY or SUBSCRIBER”. If you wish to run ttAudit on the ACTIVE data store in a highly available configuration, perform these tasks in this exact order: 1) Make sure the jmsxla.xml file contains the line replicatedBookmark=”yes” under the audit topic; 2) Run the auditTablesDDLTimesTen.sql script on the planned ACTIVE data store that you wish to audit; 3) run your CREATE ACTIVE STANDBY PAIR command; 4) start the replication agent; 5) run the sql command “call ttRepStateSet(‘ACTIVE”); 6) Create the STANDBY server with ttRepAdmin –duplicate; 7) Run the auditTablesDDLauditDB.sql script in your Oracle database.; 8) start ttAudit by editing the supplied runAudit.sh and running it. By default, ttAudit will create a replicated bookmark. If you run the sql command “call ttLogHolds;” on both the ACTIVE and STANDBY databases, you should see that the XLA bookmark is incrementing. If a failover or switchover occurs, ttAudit will re-start. You must start up ttAudit on the new ACTIVE server when the failover occurs. (If you are using TimesTen replication with Oracle Clusterware, Clusterware can be configured to launch ttAudit upon failover.) Since the XLA bookmark is replicated and persisted to TimesTen’s log file on disk, ttAudit will pick up where it left off without transaction loss. Dropping Tables When Auditing is Running: You cannot drop tables that are being audited. If you wish to disable auditing for the entire database, see “Disabling Auditing” above. If you want to drop a single table, you must first disable auditing for that table by running a SQL command. For example, if your owner/schema is JOE, and your table is MYTABLE: update ttaudit.audittables set auditEnabled = ‘N’ where fulltablename =‘JOE.MYTABLE’; commit; ttAudit.java must be running. It will detect the change to the audittables table, restart, and unsubscribe to that table. Once this happens, you can execute DROP TABLE. If you wish to reenable auditing, update the above column to ‘Y’. Running ttAudit on a TimesTen Replication STANDBY or SUBSCRIBER: If TimesTen is running with TimesTen-to-TimesTen replication, normally ttAudit is run on the ACTIVE or MASTER server. However, you may run ttAudit on a read-only STANDBY or subscriber. To do this, perform the following steps: 1) Set up the planned ACTIVE TimesTen data store for ttAudit as specified in the tutorial above. 2) Launch ttAudit on the ACTIVE server for at least a minute or two; this populates the list of subscribed tables in the ttAudit.auditTables table. You may then abort the ttAudit application on the ACTIVE if you wish. 3) Set up TimesTen replication per the TimesTen Replication Guide; if the entire data store is not replicated, then at minimum, all tables owned by ttAudit must be replicated, as well as all tables what you wish to audit. 4) Select a bookmark name that is different from the bookmark name used on ttAudit running on the ACTIVE. 5) Execute the following SQL script on the ACTIVE; in the below example, the selected bookmark name for ttAudit running on the read-only subscriber is “bookmark2”: Insert into ttaudit.auditTables select fullTablename, ’bookmark2’, ’Y’, materializedView from ttAudit.audtTables where auditEnabled = ’Y’; commit; 6) Edit the script you are using to launch ttAudit. On the java command line, add the command line argument “-runOnSubscriber” . 7) Launch ttAudit on the read-only subscriber, specifying the new bookmark name with the java command line argument, “ –bookmark bookmark2”. When ttAudit is launched, it should indicate that it is subscribing to your tables with messages in the log. Manually Removing the XLA Bookmark: The above procedure, “Dropping Tables When Auditing is Running”, automatically un-subscribes a table to auditing if ttAudit is running. This allows for dropping of that table. The above procedure, “Disabling Auditing”, automatically removes the XLA bookmark if ttAudit is running. If ttAudit is not running, or you wish to un-subscribe a table to auditing or remove the bookmark manually, execute the following SQL commands in TimesTen: Find the name of the bookmark: call ttLogHolds; Run this command for every table you wish to drop: ttXlaUnsubscribe(‘OWNER.TABLE’,’bookmarkName’); Once all tables are un-subscribed, remove the bookmark: call ttXlaBookmarkDelete(‘bookmarkName’); Recommended sys.odbc.ini Settings PrivateCommands=1 LogBufMB=1024 LogFileSize=1024 LogBufParallelism = 8 (if you have at least 12 CPU cores on your system) MemoryLock=4 RecoveryThreads = number of CPU cores on your system – 2 DatabaseCharacterSet = the same character set as your Oracle DB ttAudit Command Line Options -convertBinary: This option is recommended. If you are using an Oracle database to store audit data, this option will cause ttAudit to convert binary/raw data to a readable string. For example, the binary “0x0123” will be shown in the ttauditcolumns.new_column_value column as “0123”. -topic: The name of the JMS topic, which defaults to “audit”. If this is changed, the jmsxla.xml file must be changed also to define the new topic name. -bookmark: The name of the bookmark you wish to create. The default is “ttauditbookmark”. You can run multiple instances of ttAudit simultaneously if you specify the –bookmark, -ignoreDDL, and – ignoreMV options on the command line of the second (and subsequent) instances of ttAudit; you would also change the bookmark column in the ttaudit.auditables table for the tables you want monitored on this other bookmark. -fullInsertAudit: This specifies that all columns in a table are audited when an INSERT occurs. This generates a massive amount of data in the ttaudit.auditColumns table. If this option is not specified, only the columns in the primary key are audited on INSERT. For UPDATEs, all columns that are updated, and the primary keys, are audited no matter the command line option. -jdbcBatchSize: This is the batch size used for Oracle database JDBC batching. The default is 20, which in tests is typically the optimal value. Changing this value may improve the performance of the writes to Oracle. If you are using the TimesTen database to store auditing information, this option is ignored. -heartbeatInterval: The amount of time in milliseconds between updates to the ttaudit.auditmonitor table. This table is constantly updated, so the XLA bookmark is constantly advancing. (If the bookmark was not advancing, log files are not purged upon a TimesTen checkpoint, and eventually, log files would accumulate until disk space was exhausted.) The default is 5000 milliseconds, which is recommended. -dateFormat: The default format is “YYYY-MM-DD HH24:MI:SS”. This is the way date and timestamp data is formatted in auditing. If you want something else, you can specify a different format. See the javadoc for SimpleDateFormat: http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html -xlaUrl: The JDBC URL for the TimesTen database you are auditing. This is passed to getConnection(). It must be of the format jdbc:timesten:direct:DSN, where DSN is your DSN as defined in sys.odbc.ini. Client/server connections are not permitted. This DSN must match the DSN definition for the “audit” topic in the jmsxla.xml file. --xlaUsername, -xlaPassword: The user ID and password for the TimesTen database you are auditing. The auditTablesDDLTimesTen.sql script creates a user ID called ttAudit for this purpose. The default password is ttAudit. This user must have permission to read and write to the tables listed in auditTablesDDLTimesTen.sql . --dbUsername, -dbPassword: The user ID and password for the database that is storing the auditing data. The auditTablesDDLauditDB.sql script creates a user ID called ttAudit for this purpose. The default password is ttAudit. This user must have permission to read and write to the tables listed in auditTablesDDLauditDB.sql . -dbDriver: The JDBC driver for the database that is storing the audit information. This is either com.timesten.jdbc.TimesTenDriver or oracle.jdbc.OracleDriver. No other drivers have been tested. -dbUrl: The JDBC url for the database that is storing the audit data. See runAudit.sh for examples with the Oracle database. -ignoreDDL: By default, ttAudit automatically detects CREATE TABLE and CREATE MATERIALIZED VIEW statements and automatically audits the new tables. Use this command line option if you do not want this behavior. If you use this option and want new tables audited, you will need to re-start the ttAudit application, or you need to add a row to the ttaudit.audittables table with the owner and name of your table in the FullTableName column (all CAPS) and the name of the bookmark that ttAudit is using, along with a ‘Y’ in the auditEnabled column. -ignoreMV: By default, ttAudit monitors changes in materialized view data. Use this flag if you do not want to audit materialized views. -logFile: By default, ttAudit sends all messages and errors to standard out. With this option, you can specify a filename that contains its messages and errors. -maxColumnAuditLength: Data that is audited is truncated at 1024 characters by default. This option changes the maximum length. You will also need to change the length of the VARCHAR2(1024) columns in ttAuditDDLTimesTen.sql and ttAuditDDLauditDB.sql scripts. -tsColumnName: This is the name of the column in your audited tables that contains a timestamp of when the row was updated. The default is “UPDATE_TIME”. If no such column is specified or found, ttAudit will store the current system time. NOTE: Without this option, the current system time will be the time that ttAudit received the message through JMS/XLA, NOT the time of the transaction. -userColumnName: This is the name of the column in your audited tables that contains a username of the user that updated the row. The default is “UPDATE_USER”. -noDatabaseUserAudit: TimesTen’s XLA API does not provide information on the database user ID that executed the transaction. However, an algorithm is provided that can in most cases determine the user ID by scanning the list of prepared SQL commands in the database. This is the database login ID, not a login ID of the application. If this option is specified, it does not do this; rather, it relies on a column in your tables that is called something like “USER_UPDATED” to determine the user ID of the transaction. -outFile: Rather than storing auditing information in a database, this option stores it as a file in the file system. By default, the delimiter character is a comma between fields. (this character can be changed with –delimiter) . The file can be loaded into Oracle using an External Table; see the externalTableDDL.sql script for a full description of this file and instructions on how to access it in Oracle as an External Table. Specify the full path to the filename after –outFile. -stringCharacter: By default, if –outfile is used, character strings are enclosed in double quotes (“). You can specify another character with this option. -saveDataType: By default, the ttAudit.ttAuditColumns.data_type column contains one of two values: -2 (java.sql.Types.BINARY) for binary data or 12 for anything else. This option saves more detailed information about the data type. See externalTableDDL.sql for more information. -verbose: If specified, detailed information about every transaction is send to standard out. Troubleshooting 1) I get an error when I connect, “cannot find ttlibjdbc.so in java.library.path”. TimesTen requires a native library. You must set LD_LIBRARY_PATH in Linux or Solaris or PATH on Windows. This is done in the runAudit.sh script. 2) There are duplicates in the audit tables. This is a known problem. XLA is an asynchronous API. It is possible that if the ttAudit application is started and restarted, that duplicate transactions may appear. TimesTen produces a unique transaction ID for every time that an application issues a COMMIT; this ID is in the column trx_id. 3) The Oracle database isn’t accepting the audit information as fast as TimesTen is writing it. This is a known problem. The Oracle database could lag behind if it is being used for the audit information. One alternative is to write the audit information to the file system with –outFile, then bulk load it into Oracle using an External Table; see externalTableDDL.sql . 4) When attempting to drop a table, I get an error, “TT8068: cannot drop a table that is subscribed by an XLA bookmark.” You cannot drop tables that are being audited. If you wish to drop all tables in the database, see “Disabling Auditing” above. If you wish to drop a single table, see “Dropping Tables When Auditing is Running” above. If you wish to unsubscribe a table and/or drop the XLA bookmark manually, see “Manually Removing the XLA Bookmark” above. 5) When I use a TimesTen database to store audit data, BINARY data is not displayed properly. Use an Oracle database to store audit data. 6) When I use an Oracle database to store audit data, BINARY data is not displayed properly, and I cannot query BINARY data. Note how UTL_RAW.CAST_TO_RAW is used in auditTablesDDLauditDB, creating a function called ttAuditFnc.rawFormat(). This is used in the sample scripts auditQuery01Oracle.sql and auditQueryOracleUUID.sql. 7) My applications constantly create and drop tables. The ttAudit program keeps re-starting when this happens. Use the –ignoreDDL option on the command line. When you create a table that you want to audit, you will need to add a row to the ttaudit.audittables table yourself. For example: CREATE TABLE myUser.myTable(id NUMBER NOT NULL PRIMARY KEY) INSERT INTO ttAudit.auditTables (fullTableName, bookmarkName, auditEnables,materializedView) VALUES (‘MYUSER.MYTABLE’,’auditBookmark’,’Y’,’N’); 8) I get the error “PLSQL_MEMORY_ADDRESS already in use” when starting ttAudit. This occurs when you attempt to connect directly to two separate TimesTen databases. If you are using only one TimesTen database, the cause of this error is probably that the DSN in the TTAUDIT_XLAURL of your runAudit.sh script does not match the DSN in the “audit” topic of your jmsxla.xml file. If you are trying to audit two TimesTen databases on the same system, check the TimesTen documentation for appropriate settings of PLSQL_MEMORY_ADDRESS.