mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Link Database Earliest and Latest Point in time with DryRun (#17506)
This commit is contained in:
committed by
GitHub
parent
b48f392ab2
commit
08d3803453
@@ -9,14 +9,14 @@ import * as azExt from 'az-ext';
|
||||
import * as vscode from 'vscode';
|
||||
import { UserCancelledError } from '../common/api';
|
||||
import { Deferred } from '../common/promise';
|
||||
import { parseIpAndPort } from '../common/utils';
|
||||
import { getTimeStamp, parseIpAndPort } from '../common/utils';
|
||||
import * as loc from '../localizedConstants';
|
||||
import { ConnectToMiaaSqlDialog } from '../ui/dialogs/connectMiaaDialog';
|
||||
import { AzureArcTreeDataProvider } from '../ui/tree/azureArcTreeDataProvider';
|
||||
import { ControllerModel, Registration } from './controllerModel';
|
||||
import { ResourceModel } from './resourceModel';
|
||||
|
||||
export type DatabaseModel = { name: string, status: string, lastBackup: string };
|
||||
export type DatabaseModel = { name: string, status: string, earliestBackup: string, lastBackup: string };
|
||||
export type RPModel = { recoveryPointObjective: string, retentionDays: string };
|
||||
export type PITRModel = {
|
||||
instanceName: string,
|
||||
@@ -27,7 +27,9 @@ export type PITRModel = {
|
||||
restorePoint: string,
|
||||
earliestPitr: string,
|
||||
latestPitr: string,
|
||||
destDbName: string
|
||||
};
|
||||
|
||||
export const systemDbs = ['master', 'msdb', 'tempdb', 'model'];
|
||||
export class MiaaModel extends ResourceModel {
|
||||
|
||||
@@ -44,12 +46,20 @@ export class MiaaModel extends ResourceModel {
|
||||
recoveryPointObjective: '',
|
||||
retentionDays: ''
|
||||
};
|
||||
private _databaseTimeWindow: Map<string, string[]>;
|
||||
|
||||
private _refreshPromise: Deferred<void> | undefined = undefined;
|
||||
|
||||
private _pitrArgs = {
|
||||
destName: '',
|
||||
managedInstance: '',
|
||||
time: '',
|
||||
noWait: true,
|
||||
dryRun: false
|
||||
};
|
||||
constructor(_controllerModel: ControllerModel, private _miaaInfo: MiaaResourceInfo, registration: Registration, private _treeDataProvider: AzureArcTreeDataProvider) {
|
||||
super(_controllerModel, _miaaInfo, registration);
|
||||
this._azApi = <azExt.IExtension>vscode.extensions.getExtension(azExt.extension.name)?.exports;
|
||||
this._databaseTimeWindow = new Map<string, string[]>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,6 +102,7 @@ export class MiaaModel extends ResourceModel {
|
||||
this.configLastUpdated = new Date();
|
||||
this.rpSettings.retentionDays = this._config?.spec?.backup?.retentionPeriodInDays?.toString() ?? '';
|
||||
this._onConfigUpdated.fire(this._config);
|
||||
this._onDatabasesUpdated.fire(this._databases);
|
||||
} catch (err) {
|
||||
// If an error occurs show a message so the user knows something failed but still
|
||||
// fire the event so callers can know to update (e.g. so dashboards don't show the
|
||||
@@ -138,6 +149,12 @@ export class MiaaModel extends ResourceModel {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of databases and adds backup earliest and latest point in time
|
||||
* information, this could be used as an upper and lower time limit for restoring
|
||||
* backup.
|
||||
*/
|
||||
public async getDatabases(promptForConnection: boolean = true): Promise<void> {
|
||||
if (!this._connectionProfile) {
|
||||
await this.getConnectionProfile(promptForConnection);
|
||||
@@ -158,10 +175,21 @@ export class MiaaModel extends ResourceModel {
|
||||
if (!databases) {
|
||||
throw new Error('Could not fetch databases');
|
||||
}
|
||||
if (databases.length > 0 && typeof (databases[0]) === 'object') {
|
||||
this._databases = (<azdata.DatabaseInfo[]>databases).map(db => { return { name: db.options['name'], status: db.options['state'], lastBackup: db.options['lastBackup'] }; });
|
||||
} else {
|
||||
this._databases = (<string[]>databases).map(db => { return { name: db, status: '-', lastBackup: '' }; });
|
||||
else {
|
||||
if (databases.length > 0 && typeof (databases[0]) === 'object') {
|
||||
for (let i in databases) {
|
||||
const di: azdata.DatabaseInfo = <azdata.DatabaseInfo>databases[i];
|
||||
const name = di.options['name'];
|
||||
await this.executeDryRun(di.options['name']);
|
||||
const dm: DatabaseModel = {
|
||||
name: name, status: di.options['state'], earliestBackup: this._databaseTimeWindow.get(name)?.[0] ?? '',
|
||||
lastBackup: this._databaseTimeWindow.get(name)?.[1] ?? ''
|
||||
};
|
||||
this._databases[i] = dm;
|
||||
}
|
||||
} else {
|
||||
this._databases = (<string[]>databases).map(db => { return { name: db, status: '-', earliestBackup: '', lastBackup: '' }; });
|
||||
}
|
||||
}
|
||||
this.databasesLastUpdated = new Date();
|
||||
this._onDatabasesUpdated.fire(this._databases);
|
||||
@@ -206,4 +234,33 @@ export class MiaaModel extends ResourceModel {
|
||||
await this._treeDataProvider.saveControllers();
|
||||
}
|
||||
|
||||
protected async executeDryRun(dbName: string): Promise<void> {
|
||||
// Allow next dry Run to be executed only after 5(300000 ms ) minutes from current time as the log backups are
|
||||
// generated only at 5 minutes interval
|
||||
if ((systemDbs.indexOf(dbName) === -1) && (Date.now() - getTimeStamp(this._databaseTimeWindow.get(dbName)?.[1]) >= 300000)) {
|
||||
try {
|
||||
//Execute dryRun for earliestTime and save latest time as well so there is one call to az cli
|
||||
this._pitrArgs.destName = dbName + '-' + Date.now().toString();
|
||||
this._pitrArgs.managedInstance = this.info.name;
|
||||
this._pitrArgs.time = new Date().toISOString();
|
||||
this._pitrArgs.noWait = false;
|
||||
this._pitrArgs.dryRun = true;
|
||||
const result = await this._azApi.az.sql.midbarc.restore(
|
||||
dbName, this._pitrArgs, this.controllerModel.info.namespace, this.controllerModel.azAdditionalEnvVars);
|
||||
const restoreResult = result.stdout;
|
||||
if (restoreResult) {
|
||||
const earliestTime = restoreResult['earliestRestoreTime'];
|
||||
const latestTime = restoreResult['latestRestoreTime'];
|
||||
console.log(loc.earliestPitrRestorePoint + '-' + dbName + ':' + earliestTime);
|
||||
console.log(loc.latestpitrRestorePoint + '-' + dbName + ':' + latestTime);
|
||||
this._databaseTimeWindow.set(dbName, [earliestTime, latestTime]);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.log(loc.pitr + ' ' + loc.failed + ':' + err);
|
||||
this._databaseTimeWindow.set(dbName, ['', '']);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user