support Oracle flash back; auto-fix metric type; compile ojdbc

This commit is contained in:
yangdsh 2019-11-23 20:21:51 +00:00 committed by Dana Van Aken
parent 5555ead3a3
commit dceee6e0ba
8 changed files with 111 additions and 11 deletions

View File

@ -52,6 +52,7 @@ dependencies {
// For Oracle, create the directory client/controller/libs and copy the driver // For Oracle, create the directory client/controller/libs and copy the driver
// (e.g., ojdbc8.jar) into it. The driver must be manually downloaded from Oracle. // (e.g., ojdbc8.jar) into it. The driver must be manually downloaded from Oracle.
dependencies {compile files('lib/ojdbc8.jar')}
} }
run { run {

View File

@ -68,6 +68,10 @@ PG_DATADIR = '/var/lib/postgresql/9.6/main'
# ORACLE-SPECIFIC OPTIONS >>> # ORACLE-SPECIFIC OPTIONS >>>
ORACLE_AWR_ENABLED = False ORACLE_AWR_ENABLED = False
ORACLE_FLASH_BACK = True
RESTORE_POINT = 'tpcc_point'
RECOVERY_FILE_DEST = '/opt/oracle/oradata/ORCL'
RECOVERY_FILE_DEST_SIZE = '15G'
#========================================================== #==========================================================

View File

@ -415,15 +415,23 @@ def upload_batch(result_dir=None, sort=True, upload_code=None):
@task @task
def dump_database(): def dump_database():
dumpfile = os.path.join(dconf.DB_DUMP_DIR, dconf.DB_NAME + '.dump') dumpfile = os.path.join(dconf.DB_DUMP_DIR, dconf.DB_NAME + '.dump')
if file_exists(dumpfile): if not dconf.ORACLE_FLASH_BACK and file_exists(dumpfile):
LOG.info('%s already exists ! ', dumpfile) LOG.info('%s already exists ! ', dumpfile)
return False return False
LOG.info('Dump database %s to %s', dconf.DB_NAME, dumpfile) if dconf.ORACLE_FLASH_BACK:
LOG.info('create restore point %s for database %s in %s', dconf.RESTORE_POINT,
dconf.DB_NAME, dconf.RECOVERY_FILE_DEST)
else:
LOG.info('Dump database %s to %s', dconf.DB_NAME, dumpfile)
if dconf.DB_TYPE == 'oracle': if dconf.DB_TYPE == 'oracle':
run_sql_script('dumpOracle.sh', dconf.DB_USER, dconf.DB_PASSWORD, if dconf.ORACLE_FLASH_BACK:
dconf.DB_NAME, dconf.DB_DUMP_DIR) run_sql_script('createRestore.sh', dconf.RESTORE_POINT,
dconf.RECOVERY_FILE_DEST_SIZE, dconf.RECOVERY_FILE_DEST)
else:
run_sql_script('dumpOracle.sh', dconf.DB_USER, dconf.DB_PASSWORD,
dconf.DB_NAME, dconf.DB_DUMP_DIR)
elif dconf.DB_TYPE == 'postgres': elif dconf.DB_TYPE == 'postgres':
run('PGPASSWORD={} pg_dump -U {} -h {} -F c -d {} > {}'.format( run('PGPASSWORD={} pg_dump -U {} -h {} -F c -d {} > {}'.format(
@ -434,19 +442,28 @@ def dump_database():
return True return True
@task
def clean_recovery():
run_sql_script('removeRestore.sh', dconf.RESTORE_POINT)
cmds = ("""rman TARGET / <<EOF\nDELETE ARCHIVELOG ALL;\nexit\nEOF""")
run(cmds)
@task @task
def restore_database(): def restore_database():
dumpfile = os.path.join(dconf.DB_DUMP_DIR, dconf.DB_NAME + '.dump') dumpfile = os.path.join(dconf.DB_DUMP_DIR, dconf.DB_NAME + '.dump')
if not file_exists(dumpfile): if not dconf.ORACLE_FLASH_BACK and not file_exists(dumpfile):
raise FileNotFoundError("Database dumpfile '{}' does not exist!".format(dumpfile)) raise FileNotFoundError("Database dumpfile '{}' does not exist!".format(dumpfile))
LOG.info('Start restoring database') LOG.info('Start restoring database')
if dconf.DB_TYPE == 'oracle': if dconf.DB_TYPE == 'oracle':
# You must create a directory named dpdata through sqlplus in your Oracle database if dconf.ORACLE_FLASH_BACK:
# The following script assumes such directory exists. run_sql_script('flashBack.sh', dconf.RESTORE_POINT)
drop_user() clean_recovery()
create_user() else:
run_sql_script('restoreOracle.sh', dconf.DB_USER, dconf.DB_NAME) drop_user()
create_user()
run_sql_script('restoreOracle.sh', dconf.DB_USER, dconf.DB_NAME)
elif dconf.DB_TYPE == 'postgres': elif dconf.DB_TYPE == 'postgres':
drop_database() drop_database()
create_database() create_database()

View File

@ -0,0 +1,11 @@
#!/bin/sh
# Change log mode
sqlplus / as sysdba <<EOF
shutdown immediate
startup mount
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE OPEN;
quit
EOF

View File

@ -0,0 +1,33 @@
#!/bin/sh
RESTORE_POINT="$1"
SIZE="$2"
RECOVERY_FILE="$3"
# Make sure the physical directory exists
mkdir -p "$DP_PATH"
# Set recovery file and restore point
sqlplus / as sysdba <<EOF
DECLARE
rfdexists INTEGER;
BEGIN
SELECT COUNT(*) INTO rfdexists FROM V\$RECOVERY_FILE_DEST WHERE name='$RECOVERY_FILE';
IF (rfdexists = 0) then
EXECUTE IMMEDIATE 'ALTER SYSTEM SET DB_RECOVERY_FILE_DEST_SIZE = $SIZE';
EXECUTE IMMEDIATE 'ALTER SYSTEM SET DB_RECOVERY_FILE_DEST = $RECOVERY_FILE';
END IF;
DBMS_OUTPUT.PUT_LINE(rfdexists);
END;
DECLARE
rpexists INTEGER;
BEGIN
SELECT COUNT(*) INTO rpexists FROM v\\\\\$restore_point WHERE name='$RESTORE_POINT';
IF (rpexists = 0) then
EXECUTE IMMEDIATE 'CREATE RESTORE POINT $RESTORE_POINT GUARANTEE FLASHBACK DATABASE';
END IF;
DBMS_OUTPUT.PUT_LINE(rpexists);
END;
quit
EOF

View File

@ -0,0 +1,13 @@
#!/bin/sh
RESTORE_POINT="$1"
# Flash back
sqlplus / as sysdba <<EOF
SHUTDOWN IMMEDIATE
STARTUP MOUNT
FLASHBACK DATABASE TO RESTORE POINT $RESTORE_POINT;
ALTER DATABASE OPEN RESETLOGS;
quit
EOF

View File

@ -0,0 +1,10 @@
#!/bin/sh
RESTORE_POINT="$1"
# Remove RESTORE Point
sqlplus / as sysdba <<EOF
'DROP RESTORE POINT $RESTORE_POINT
quit
EOF

View File

@ -3,6 +3,8 @@
# #
# Copyright (c) 2017-18, Carnegie Mellon University Database Group # Copyright (c) 2017-18, Carnegie Mellon University Database Group
# #
import logging
from collections import OrderedDict from collections import OrderedDict
from website.models import KnobCatalog, KnobUnitType, MetricCatalog from website.models import KnobCatalog, KnobUnitType, MetricCatalog
@ -10,6 +12,8 @@ from website.types import BooleanType, MetricType, VarType
from website.utils import ConversionUtil from website.utils import ConversionUtil
from .. import target_objectives from .. import target_objectives
LOG = logging.getLogger(__name__)
# pylint: disable=no-self-use # pylint: disable=no-self-use
class BaseParser: class BaseParser:
@ -300,7 +304,7 @@ class BaseParser:
'Invalid metric type: {}'.format(metric.metric_type)) 'Invalid metric type: {}'.format(metric.metric_type))
return valid_metrics, diffs return valid_metrics, diffs
def calculate_change_in_metrics(self, metrics_start, metrics_end): def calculate_change_in_metrics(self, metrics_start, metrics_end, fix_metric_type=True):
adjusted_metrics = {} adjusted_metrics = {}
for met_name, start_val in list(metrics_start.items()): for met_name, start_val in list(metrics_start.items()):
end_val = metrics_end[met_name] end_val = metrics_end[met_name]
@ -316,6 +320,13 @@ class BaseParser:
adj_val = end_val - start_val adj_val = end_val - start_val
else: # MetricType.STATISTICS or MetricType.INFO else: # MetricType.STATISTICS or MetricType.INFO
adj_val = end_val adj_val = end_val
if fix_metric_type:
if adj_val < 0:
adj_val = end_val
LOG.debug("Changing metric %s from COUNTER to STATISTICS", met_name)
metric_fixed = self.metric_catalog_[met_name]
metric_fixed.metric_type = MetricType.STATISTICS
metric_fixed.save()
assert adj_val >= 0, \ assert adj_val >= 0, \
'{} wrong metric type: {} (start={}, end={}, diff={})'.format( '{} wrong metric type: {} (start={}, end={}, diff={})'.format(
met_name, MetricType.name(met_info.metric_type), start_val, met_name, MetricType.name(met_info.metric_type), start_val,