mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
1) Added support for SYSTEM, CONCURRENTLY and TABLESPACE options in REINDEX. #6381
2) Added new/missing options to the VACUUM command. #6397 3) Added SKIP_LOCKED and BUFFER_USAGE_LIMIT option to Analyze command. #6415
This commit is contained in:
parent
e177344ae1
commit
a460644ae8
Binary file not shown.
Before Width: | Height: | Size: 52 KiB |
BIN
docs/en_US/images/maintenance_analyze.png
Normal file
BIN
docs/en_US/images/maintenance_analyze.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 114 KiB |
BIN
docs/en_US/images/maintenance_cluster.png
Normal file
BIN
docs/en_US/images/maintenance_cluster.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 62 KiB |
BIN
docs/en_US/images/maintenance_reindex.png
Normal file
BIN
docs/en_US/images/maintenance_reindex.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 99 KiB |
BIN
docs/en_US/images/maintenance_vacuum.png
Normal file
BIN
docs/en_US/images/maintenance_vacuum.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 178 KiB |
@ -7,36 +7,109 @@
|
|||||||
Use the *Maintenance* dialog to VACUUM, ANALYZE, REINDEX or CLUSTER a database
|
Use the *Maintenance* dialog to VACUUM, ANALYZE, REINDEX or CLUSTER a database
|
||||||
or selected database objects.
|
or selected database objects.
|
||||||
|
|
||||||
.. image:: images/maintenance.png
|
|
||||||
:alt: Maintenance dialog
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
While this utility is useful for ad-hoc maintenance purposes, you are encouraged
|
While this utility is useful for ad-hoc maintenance purposes, you are encouraged
|
||||||
to perform automatic VACUUM jobs on a regular schedule.
|
to perform automatic VACUUM jobs on a regular schedule.
|
||||||
|
|
||||||
Select a button next to *Maintenance operation* to specify the type of
|
Select a button next to *Maintenance operation* to specify the type of
|
||||||
maintenance:
|
maintenance:
|
||||||
|
|
||||||
|
.. image:: images/maintenance_vacuum.png
|
||||||
|
:alt: Maintenance dialog
|
||||||
|
:align: center
|
||||||
|
|
||||||
* Click *VACUUM* to scan the selected database or table to reclaim storage used
|
* Click *VACUUM* to scan the selected database or table to reclaim storage used
|
||||||
by dead tuples.
|
by dead tuples.
|
||||||
|
|
||||||
* Move the *FULL* switch to the *Yes* position to compact tables by writing
|
* Move the *FULL* switch to the *Yes* position to compact tables by writing
|
||||||
a completely new version of the table file without dead space. The default
|
a completely new version of the table file without dead space.
|
||||||
is *No*.
|
|
||||||
|
|
||||||
* Move the *FREEZE* switch to the *Yes* position to freeze data in a table
|
* Move the *FREEZE* switch to the *Yes* position to freeze data in a table
|
||||||
when it will have no further updates. The default is *No*.
|
when it will have no further updates.
|
||||||
|
|
||||||
* Move the *ANALYZE* switch to the *Yes* position to issue ANALYZE commands
|
* Move the *ANALYZE* switch to the *Yes* position to issue ANALYZE commands
|
||||||
whenever the content of a table has changed sufficiently. The default is
|
whenever the content of a table has changed sufficiently.
|
||||||
*No*.
|
|
||||||
|
* Move the *DISABLE PAGE SKIPPING* switch to the *Yes* position to disables
|
||||||
|
all page-skipping behavior.
|
||||||
|
|
||||||
|
* Move the *SKIP LOCKED* switch to the *Yes* position to specifies that
|
||||||
|
VACUUM should not wait for any conflicting locks to be released when
|
||||||
|
beginning work on a relation. This option is available from v12 onwards.
|
||||||
|
|
||||||
|
* Move the *TRUNCATE* switch to the *Yes* position to specifies that VACUUM
|
||||||
|
should attempt to truncate off any empty pages at the end of the table and
|
||||||
|
allow the disk space for the truncated pages to be returned to the operating
|
||||||
|
system. This option is available from v12 onwards.
|
||||||
|
|
||||||
|
* Move the *PROCESS TOAST* switch to the *Yes* position to specifies that
|
||||||
|
VACUUM should attempt to process the corresponding TOAST table for each
|
||||||
|
relation, if one exists. This option is available from v14 onwards.
|
||||||
|
|
||||||
|
* Move the *PROCESS MAIN* switch to the *Yes* position to specifies that
|
||||||
|
VACUUM should attempt to process the main relation. This option is available
|
||||||
|
from v16 onwards.
|
||||||
|
|
||||||
|
* Move the *SKIP DATABASE STATS* switch to the *Yes* position to specifies
|
||||||
|
that VACUUM should skip updating the database-wide statistics about oldest
|
||||||
|
unfrozen XIDs. This option is available from v16 onwards.
|
||||||
|
|
||||||
|
* Move the *ONLY DATABASE STATS* switch to the *Yes* position to specifies
|
||||||
|
that VACUUM should do nothing except update the database-wide statistics
|
||||||
|
about oldest unfrozen XIDs . This option is available from v16 onwards.
|
||||||
|
|
||||||
|
* Use the *INDEX CLEANUP* field to force VACUUM to process indexes when there
|
||||||
|
are more than zero dead tuples.
|
||||||
|
|
||||||
|
* Use the *PARALLEL* field to specify index vacuum and index cleanup phases
|
||||||
|
of VACUUM in parallel using integer background workers. This option is
|
||||||
|
available from v13 onwards.
|
||||||
|
|
||||||
|
* Use the *BUFFER USAGE LIMIT* field to specifies the Buffer Access Strategy
|
||||||
|
ring buffer size for VACUUM. This size is used to calculate the number of
|
||||||
|
shared buffers which will be reused as part of this strategy. This option
|
||||||
|
is available from v16 onwards
|
||||||
|
|
||||||
|
|
||||||
|
.. image:: images/maintenance_analyze.png
|
||||||
|
:alt: Maintenance dialog
|
||||||
|
:align: center
|
||||||
|
|
||||||
* Click *ANALYZE* to update the stored statistics used by the query planner.
|
* Click *ANALYZE* to update the stored statistics used by the query planner.
|
||||||
This enables the query optimizer to select the fastest query plan for optimal
|
This enables the query optimizer to select the fastest query plan for optimal
|
||||||
performance.
|
performance.
|
||||||
|
|
||||||
|
* Move the *SKIP LOCKED* switch to the *Yes* position to specifies that
|
||||||
|
ANALYZE should not wait for any conflicting locks to be released when
|
||||||
|
beginning work on a relation. This option is available from v12 onwards.
|
||||||
|
|
||||||
|
* Use the *BUFFER USAGE LIMIT* field to specifies the Buffer Access Strategy
|
||||||
|
ring buffer size for ANALYZE. This size is used to calculate the number of
|
||||||
|
shared buffers which will be reused as part of this strategy. This option
|
||||||
|
is available from v16 onwards
|
||||||
|
|
||||||
|
.. image:: images/maintenance_reindex.png
|
||||||
|
:alt: Maintenance dialog
|
||||||
|
:align: center
|
||||||
|
|
||||||
* Click *REINDEX* to rebuild any index in case it has degenerated due to the
|
* Click *REINDEX* to rebuild any index in case it has degenerated due to the
|
||||||
insertion of unusual data patterns. This happens, for example, if you insert
|
insertion of unusual data patterns. This happens, for example, if you insert
|
||||||
rows with increasing index values, and delete low index values.
|
rows with increasing index values, and delete low index values.
|
||||||
|
|
||||||
|
* Move the *SYSTEM* switch to the *Yes* position to recreate all indexes
|
||||||
|
on system catalogs within the current database. This option is enabled
|
||||||
|
only when database object is selected.
|
||||||
|
|
||||||
|
* Move the *CONCURRENTLY* switch to the *Yes* position to rebuild the index
|
||||||
|
without taking any locks that prevent concurrent inserts, updates, or
|
||||||
|
deletes on the table. This option is available from v12 onwards.
|
||||||
|
|
||||||
|
* Use the *TABLESPACE* field to specifies that indexes will be rebuilt on
|
||||||
|
a new tablespace. This option is available from v14 onwards.
|
||||||
|
|
||||||
|
.. image:: images/maintenance_cluster.png
|
||||||
|
:alt: Maintenance dialog
|
||||||
|
:align: center
|
||||||
|
|
||||||
* Click *CLUSTER* to instruct PostgreSQL to cluster the selected table.
|
* Click *CLUSTER* to instruct PostgreSQL to cluster the selected table.
|
||||||
|
|
||||||
To exclude status messages from the process output, move the *Verbose Messages*
|
To exclude status messages from the process output, move the *Verbose Messages*
|
||||||
@ -47,4 +120,4 @@ to exit the dialog without performing maintenance operations, click *Cancel*.
|
|||||||
|
|
||||||
pgAdmin will run the maintenance process in background. You can view all the background
|
pgAdmin will run the maintenance process in background. You can view all the background
|
||||||
process with there running status and logs on the :ref:`Processes <processes>`
|
process with there running status and logs on the :ref:`Processes <processes>`
|
||||||
tab
|
tab.
|
||||||
|
@ -11,6 +11,7 @@ notes for it.
|
|||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
|
release_notes_7_6
|
||||||
release_notes_7_5
|
release_notes_7_5
|
||||||
release_notes_7_4
|
release_notes_7_4
|
||||||
release_notes_7_3
|
release_notes_7_3
|
||||||
|
32
docs/en_US/release_notes_7_6.rst
Normal file
32
docs/en_US/release_notes_7_6.rst
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
***********
|
||||||
|
Version 7.6
|
||||||
|
***********
|
||||||
|
|
||||||
|
Release date: 2023-08-24
|
||||||
|
|
||||||
|
This release contains a number of bug fixes and new features since the release of pgAdmin 4 v7.5.
|
||||||
|
|
||||||
|
Supported Database Servers
|
||||||
|
**************************
|
||||||
|
**PostgreSQL**: 11, 12, 13, 14 and 15
|
||||||
|
|
||||||
|
**EDB Advanced Server**: 11, 12, 13, 14 and 15
|
||||||
|
|
||||||
|
Bundled PostgreSQL Utilities
|
||||||
|
****************************
|
||||||
|
**psql**, **pg_dump**, **pg_dumpall**, **pg_restore**: 15.3
|
||||||
|
|
||||||
|
|
||||||
|
New features
|
||||||
|
************
|
||||||
|
|
||||||
|
| `Issue #6381 <https://github.com/pgadmin-org/pgadmin4/issues/6381>`_ - Added support for SYSTEM, CONCURRENTLY and TABLESPACE options in REINDEX.
|
||||||
|
| `Issue #6397 <https://github.com/pgadmin-org/pgadmin4/issues/6397>`_ - Added new/missing options to the VACUUM command.
|
||||||
|
| `Issue #6415 <https://github.com/pgadmin-org/pgadmin4/issues/6415>`_ - Added SKIP_LOCKED and BUFFER_USAGE_LIMIT option to Analyze command.
|
||||||
|
|
||||||
|
Housekeeping
|
||||||
|
************
|
||||||
|
|
||||||
|
|
||||||
|
Bug fixes
|
||||||
|
*********
|
@ -470,19 +470,19 @@ STORAGE_DIR = os.path.join(DATA_DIR, 'storage')
|
|||||||
##########################################################################
|
##########################################################################
|
||||||
DEFAULT_BINARY_PATHS = {
|
DEFAULT_BINARY_PATHS = {
|
||||||
"pg": "",
|
"pg": "",
|
||||||
"pg-10": "",
|
|
||||||
"pg-11": "",
|
"pg-11": "",
|
||||||
"pg-12": "",
|
"pg-12": "",
|
||||||
"pg-13": "",
|
"pg-13": "",
|
||||||
"pg-14": "",
|
"pg-14": "",
|
||||||
"pg-15": "",
|
"pg-15": "",
|
||||||
|
"pg-16": "",
|
||||||
"ppas": "",
|
"ppas": "",
|
||||||
"ppas-10": "",
|
|
||||||
"ppas-11": "",
|
"ppas-11": "",
|
||||||
"ppas-12": "",
|
"ppas-12": "",
|
||||||
"ppas-13": "",
|
"ppas-13": "",
|
||||||
"ppas-14": "",
|
"ppas-14": "",
|
||||||
"ppas-15": ""
|
"ppas-15": "",
|
||||||
|
"ppas-16": ""
|
||||||
}
|
}
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
@ -75,59 +75,50 @@ class Message(IProcessDesc):
|
|||||||
|
|
||||||
return "{0} ({1}:{2})".format(s.name, host, port)
|
return "{0} ({1}:{2})".format(s.name, host, port)
|
||||||
|
|
||||||
def get_op(self):
|
def get_object_msg(self):
|
||||||
op = self._check_for_vacuum()
|
msg = _("on database '{0}'").format(self.data['database'])
|
||||||
|
if 'primary_key' in self.data or 'unique_constraint' in self.data:
|
||||||
if self.data['op'] == "ANALYZE":
|
msg = _("on constraint '{0}/{1}/{2}/{3}'").format(
|
||||||
op = _('ANALYZE')
|
self.data['database'], self.data['schema'], self.data['table'],
|
||||||
if self.data['verbose']:
|
self.data['primary_key'] if 'primary_key' in self.data else
|
||||||
op += '(' + _('VERBOSE') + ')'
|
self.data['unique_constraint'])
|
||||||
|
elif 'index' in self.data:
|
||||||
if self.data['op'] == "REINDEX":
|
msg = _("on index '{0}/{1}/{2}/{3}'").format(
|
||||||
if 'schema' in self.data and self.data['schema']:
|
self.data['database'], self.data['schema'],
|
||||||
if 'primary_key' in self.data or \
|
self.data['table'], self.data['index'])
|
||||||
'unique_constraint' in self.data or \
|
elif 'table' in self.data:
|
||||||
'index' in self.data:
|
msg = _("on table '{0}/{1}/{2}'").format(
|
||||||
return _('REINDEX INDEX')
|
self.data['database'], self.data['schema'], self.data['table'])
|
||||||
else:
|
elif 'schema' in self.data:
|
||||||
return _('REINDEX TABLE')
|
msg = _("on schema '{0}/{1}'").format(self.data['database'],
|
||||||
op = _('REINDEX')
|
self.data['schema'])
|
||||||
|
return msg
|
||||||
if self.data['op'] == "CLUSTER":
|
|
||||||
op = _('CLUSTER')
|
|
||||||
|
|
||||||
return op
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def message(self):
|
def message(self):
|
||||||
res = _("{0} on database '{1}' of server {2}")
|
op = _('VACUUM')
|
||||||
return res.format(
|
if self.data['op'] == "ANALYZE":
|
||||||
self.get_op(), self.data['database'], self.get_server_name())
|
op = _('ANALYZE')
|
||||||
|
elif self.data['op'] == "REINDEX" and 'schema' not in self.data:
|
||||||
|
op = _('REINDEX')
|
||||||
|
elif self.data['op'] == "REINDEX" and 'schema' in self.data:
|
||||||
|
if 'primary_key' in self.data or 'unique_constraint' in self.data\
|
||||||
|
or 'index' in self.data:
|
||||||
|
op = _('REINDEX INDEX')
|
||||||
|
elif 'table' in self.data:
|
||||||
|
op = _('REINDEX TABLE')
|
||||||
|
else:
|
||||||
|
op = _('REINDEX SCHEMA')
|
||||||
|
elif self.data['op'] == "CLUSTER":
|
||||||
|
op = _('CLUSTER')
|
||||||
|
|
||||||
|
res = _("{0} {1} of server {2}")
|
||||||
|
return res.format(op, self.get_object_msg(), self.get_server_name())
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def type_desc(self):
|
def type_desc(self):
|
||||||
return _("Maintenance")
|
return _("Maintenance")
|
||||||
|
|
||||||
def _check_for_vacuum(self):
|
|
||||||
"""
|
|
||||||
Check for VACUUM in data and return format response.
|
|
||||||
:return: response.
|
|
||||||
"""
|
|
||||||
res = None
|
|
||||||
if self.data['op'] == "VACUUM":
|
|
||||||
res = _('VACUUM ({0})')
|
|
||||||
|
|
||||||
opts = []
|
|
||||||
if 'vacuum_full' in self.data and self.data['vacuum_full']:
|
|
||||||
opts.append(_('FULL'))
|
|
||||||
if 'vacuum_freeze' in self.data and self.data['vacuum_freeze']:
|
|
||||||
opts.append(_('FREEZE'))
|
|
||||||
if self.data['verbose']:
|
|
||||||
opts.append(_('VERBOSE'))
|
|
||||||
|
|
||||||
res = res.format(', '.join(str(x) for x in opts))
|
|
||||||
return res
|
|
||||||
|
|
||||||
def details(self, cmd, args):
|
def details(self, cmd, args):
|
||||||
return {
|
return {
|
||||||
"message": self.message,
|
"message": self.message,
|
||||||
|
@ -11,6 +11,7 @@ import Notify from '../../../../static/js/helpers/Notifier';
|
|||||||
import {getUtilityView} from '../../../../browser/static/js/utility_view';
|
import {getUtilityView} from '../../../../browser/static/js/utility_view';
|
||||||
import getApiInstance from 'sources/api_instance';
|
import getApiInstance from 'sources/api_instance';
|
||||||
import MaintenanceSchema, {getVacuumSchema} from './maintenance.ui';
|
import MaintenanceSchema, {getVacuumSchema} from './maintenance.ui';
|
||||||
|
import { getNodeListByName } from '../../../../browser/static/js/node_ajax';
|
||||||
|
|
||||||
define([
|
define([
|
||||||
'sources/gettext', 'sources/url_for', 'sources/pgadmin', 'pgadmin.browser',
|
'sources/gettext', 'sources/url_for', 'sources/pgadmin', 'pgadmin.browser',
|
||||||
@ -76,9 +77,15 @@ define([
|
|||||||
},
|
},
|
||||||
getUISchema: function(treeItem) {
|
getUISchema: function(treeItem) {
|
||||||
let treeNodeInfo = pgBrowser.tree.getTreeNodeHierarchy(treeItem);
|
let treeNodeInfo = pgBrowser.tree.getTreeNodeHierarchy(treeItem);
|
||||||
|
const selectedNode = pgBrowser.tree.selected();
|
||||||
|
let itemNodeData = pgBrowser.tree.findNodeByDomElement(selectedNode).getData();
|
||||||
|
|
||||||
return new MaintenanceSchema(
|
return new MaintenanceSchema(
|
||||||
()=>getVacuumSchema(),
|
()=>getVacuumSchema({
|
||||||
|
tablespace: ()=>getNodeListByName('tablespace', treeNodeInfo, itemNodeData, {}, (m)=>{
|
||||||
|
return (m.label != 'pg_global');
|
||||||
|
})
|
||||||
|
}),
|
||||||
{
|
{
|
||||||
nodeInfo: treeNodeInfo
|
nodeInfo: treeNodeInfo
|
||||||
}
|
}
|
||||||
@ -106,6 +113,15 @@ define([
|
|||||||
if(treeInfo?.mview) {
|
if(treeInfo?.mview) {
|
||||||
extraData['table'] = treeInfo?.mview._label;
|
extraData['table'] = treeInfo?.mview._label;
|
||||||
}
|
}
|
||||||
|
if(treeInfo?.primary_key) {
|
||||||
|
extraData['primary_key'] = treeInfo?.primary_key._label;
|
||||||
|
}
|
||||||
|
if(treeInfo?.unique_constraint) {
|
||||||
|
extraData['unique_constraint'] = treeInfo?.unique_constraint._label;
|
||||||
|
}
|
||||||
|
if(treeInfo?.index) {
|
||||||
|
extraData['index'] = treeInfo?.index._label;
|
||||||
|
}
|
||||||
extraData['save_btn_icon'] = 'done';
|
extraData['save_btn_icon'] = 'done';
|
||||||
return extraData;
|
return extraData;
|
||||||
},
|
},
|
||||||
@ -174,7 +190,7 @@ define([
|
|||||||
} else{
|
} else{
|
||||||
|
|
||||||
pgBrowser.Node.registerUtilityPanel();
|
pgBrowser.Node.registerUtilityPanel();
|
||||||
let panel = pgBrowser.Node.addUtilityPanel(pgBrowser.stdW.md),
|
let panel = pgBrowser.Node.addUtilityPanel(pgBrowser.stdW.md, pgBrowser.stdH.lg),
|
||||||
j = panel.$container.find('.obj_properties').first();
|
j = panel.$container.find('.obj_properties').first();
|
||||||
|
|
||||||
let schema = that.getUISchema(item);
|
let schema = that.getUISchema(item);
|
||||||
@ -194,7 +210,7 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
getUtilityView(
|
getUtilityView(
|
||||||
schema, treeInfo, 'select', 'dialog', j[0], panel, that.saveCallBack, extraData, 'OK', jobUrl, sqlHelpUrl, helpUrl);
|
schema, treeInfo, 'create', 'dialog', j[0], panel, that.saveCallBack, extraData, 'OK', jobUrl, sqlHelpUrl, helpUrl);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function() {
|
.catch(function() {
|
||||||
|
@ -23,44 +23,296 @@ export class VacuumSchema extends BaseUISchema {
|
|||||||
return 'op';
|
return 'op';
|
||||||
}
|
}
|
||||||
|
|
||||||
isDisabled(state) {
|
isApplicableForVacuum(state) {
|
||||||
if(state?.op) {
|
return state?.op ? state.op == 'VACUUM' : false;
|
||||||
return (state.op != 'VACUUM');
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
isApplicableForReindex(state) {
|
||||||
|
return state?.op ? state.op == 'REINDEX' : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
get baseFields() {
|
get baseFields() {
|
||||||
let obj = this;
|
let obj = this;
|
||||||
return [{
|
return [{
|
||||||
id: 'vacuum_full',
|
id: 'vacuum_full',
|
||||||
group: gettext('Vacuum'),
|
deps: ['op'],
|
||||||
disabled: function(state) {
|
|
||||||
return obj.isDisabled(state);
|
|
||||||
},
|
|
||||||
type: 'switch',
|
type: 'switch',
|
||||||
label: gettext('FULL'),
|
label: gettext('FULL'),
|
||||||
deps: ['op'],
|
inlineNext: true,
|
||||||
|
visible: function(state) {
|
||||||
|
return obj.isApplicableForVacuum(state);
|
||||||
|
},
|
||||||
|
disabled: function(state) {
|
||||||
|
if (!obj.isApplicableForVacuum(state)) {
|
||||||
|
state.vacuum_full = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}, {
|
}, {
|
||||||
id: 'vacuum_freeze',
|
id: 'vacuum_freeze',
|
||||||
deps: ['op'],
|
deps: ['op'],
|
||||||
disabled: function(state) {
|
|
||||||
return obj.isDisabled(state);
|
|
||||||
},
|
|
||||||
type: 'switch',
|
type: 'switch',
|
||||||
label: gettext('FREEZE'),
|
label: gettext('FREEZE'),
|
||||||
group: gettext('Vacuum'),
|
inlineNext: true,
|
||||||
|
visible: function(state) {
|
||||||
|
return obj.isApplicableForVacuum(state);
|
||||||
|
},
|
||||||
|
disabled: function(state) {
|
||||||
|
if (!obj.isApplicableForVacuum(state)) {
|
||||||
|
state.vacuum_freeze = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}, {
|
}, {
|
||||||
id: 'vacuum_analyze',
|
id: 'vacuum_analyze',
|
||||||
deps: ['op'],
|
deps: ['op'],
|
||||||
type: 'switch',
|
type: 'switch',
|
||||||
disabled: function(state) {
|
|
||||||
return obj.isDisabled(state);
|
|
||||||
},
|
|
||||||
label: gettext('ANALYZE'),
|
label: gettext('ANALYZE'),
|
||||||
group: gettext('Vacuum'),
|
inlineNext: true,
|
||||||
|
visible: function(state) {
|
||||||
|
return obj.isApplicableForVacuum(state);
|
||||||
|
},
|
||||||
|
disabled: function(state) {
|
||||||
|
if (!obj.isApplicableForVacuum(state)) {
|
||||||
|
state.vacuum_analyze = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
id: 'vacuum_disable_page_skipping',
|
||||||
|
deps: ['op', 'vacuum_full'],
|
||||||
|
type: 'switch',
|
||||||
|
label: gettext('DISABLE PAGE SKIPPING'),
|
||||||
|
inlineNext: true,
|
||||||
|
disabled: function(state) {
|
||||||
|
if (!obj.isApplicableForVacuum(state) || state.vacuum_full) {
|
||||||
|
state.vacuum_disable_page_skipping = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
visible: function(state) {
|
||||||
|
return obj.isApplicableForVacuum(state);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
id: 'skip_locked',
|
||||||
|
deps: ['op'],
|
||||||
|
type: 'switch',
|
||||||
|
label: gettext('SKIP LOCKED'),
|
||||||
|
inlineNext: true,
|
||||||
|
visible: function(state) {
|
||||||
|
return state?.op ? (state.op == 'VACUUM' || state.op == 'ANALYZE') : false;
|
||||||
|
},
|
||||||
|
disabled: function(state) {
|
||||||
|
if (state?.op && state.op != 'VACUUM' && state.op != 'ANALYZE') {
|
||||||
|
state.skip_locked = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
min_version: 120000,
|
||||||
|
}, {
|
||||||
|
id: 'vacuum_truncate',
|
||||||
|
deps: ['op', 'vacuum_full'],
|
||||||
|
type: 'switch',
|
||||||
|
label: gettext('TRUNCATE'),
|
||||||
|
inlineNext: true,
|
||||||
|
disabled: function(state) {
|
||||||
|
if (!obj.isApplicableForVacuum(state) || state.vacuum_full) {
|
||||||
|
state.vacuum_truncate = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
visible: function(state) {
|
||||||
|
return obj.isApplicableForVacuum(state);
|
||||||
|
},
|
||||||
|
min_version: 120000,
|
||||||
|
}, {
|
||||||
|
id: 'vacuum_process_toast',
|
||||||
|
deps: ['op'],
|
||||||
|
type: 'switch',
|
||||||
|
label: gettext('PROCESS TOAST'),
|
||||||
|
inlineNext: true,
|
||||||
|
visible: function(state) {
|
||||||
|
return obj.isApplicableForVacuum(state);
|
||||||
|
},
|
||||||
|
disabled: function(state) {
|
||||||
|
if (!obj.isApplicableForVacuum(state)) {
|
||||||
|
state.vacuum_process_toast = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
min_version: 140000,
|
||||||
|
}, {
|
||||||
|
id: 'vacuum_process_main',
|
||||||
|
deps: ['op'],
|
||||||
|
type: 'switch',
|
||||||
|
label: gettext('PROCESS MAIN'),
|
||||||
|
inlineNext: true,
|
||||||
|
visible: function(state) {
|
||||||
|
return obj.isApplicableForVacuum(state);
|
||||||
|
},
|
||||||
|
disabled: function(state) {
|
||||||
|
if (!obj.isApplicableForVacuum(state)) {
|
||||||
|
state.vacuum_process_main = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
min_version: 160000,
|
||||||
|
}, {
|
||||||
|
id: 'vacuum_skip_database_stats',
|
||||||
|
deps: ['op'],
|
||||||
|
type: 'switch',
|
||||||
|
label: gettext('SKIP DATABASE STATS'),
|
||||||
|
inlineNext: true,
|
||||||
|
visible: function(state) {
|
||||||
|
return obj.isApplicableForVacuum(state);
|
||||||
|
},
|
||||||
|
disabled: function(state) {
|
||||||
|
if (!obj.isApplicableForVacuum(state)) {
|
||||||
|
state.vacuum_skip_database_stats = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
min_version: 160000,
|
||||||
|
}, {
|
||||||
|
id: 'vacuum_only_database_stats',
|
||||||
|
deps: ['op'],
|
||||||
|
type: 'switch',
|
||||||
|
label: gettext('ONLY DATABASE STATS'),
|
||||||
|
inlineNext: true,
|
||||||
|
visible: function(state) {
|
||||||
|
return obj.isApplicableForVacuum(state);
|
||||||
|
},
|
||||||
|
disabled: function(state) {
|
||||||
|
if (!obj.isApplicableForVacuum(state)) {
|
||||||
|
state.vacuum_only_database_stats = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
min_version: 160000,
|
||||||
|
}, {
|
||||||
|
id: 'vacuum_index_cleanup',
|
||||||
|
deps: ['op', 'vacuum_full'],
|
||||||
|
type: 'select',
|
||||||
|
label: gettext('INDEX CLEANUP'),
|
||||||
|
controlProps: { allowClear: false, width: '100%' },
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: gettext('AUTO'),
|
||||||
|
value: 'AUTO',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: gettext('ON'),
|
||||||
|
value: 'ON',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: gettext('OFF'),
|
||||||
|
value: 'OFF',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
disabled: function(state) {
|
||||||
|
if (!obj.isApplicableForVacuum(state) || state.vacuum_full) {
|
||||||
|
state.vacuum_index_cleanup = undefined;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
visible: function(state) {
|
||||||
|
return obj.isApplicableForVacuum(state);
|
||||||
|
},
|
||||||
|
min_version: 120000,
|
||||||
|
}, {
|
||||||
|
id: 'vacuum_parallel',
|
||||||
|
deps: ['op', 'vacuum_full'],
|
||||||
|
type: 'int',
|
||||||
|
label: gettext('PARALLEL'),
|
||||||
|
min:0, max:1024,
|
||||||
|
visible: function(state) {
|
||||||
|
return obj.isApplicableForVacuum(state);
|
||||||
|
},
|
||||||
|
disabled: function(state) {
|
||||||
|
if (!obj.isApplicableForVacuum(state) || state.vacuum_full) {
|
||||||
|
state.vacuum_parallel = undefined;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
min_version: 130000,
|
||||||
|
}, {
|
||||||
|
id: 'buffer_usage_limit',
|
||||||
|
deps: ['op', 'vacuum_full', 'vacuum_analyze'],
|
||||||
|
type: 'text',
|
||||||
|
label: gettext('BUFFER USAGE LIMIT'),
|
||||||
|
visible: function(state) {
|
||||||
|
return state?.op ? (state.op == 'VACUUM' || state.op == 'ANALYZE') : false;
|
||||||
|
},
|
||||||
|
disabled: function(state) {
|
||||||
|
if (state?.op && ((state.op != 'VACUUM' && state.op != 'ANALYZE') || (state.op == 'VACUUM' && state.vacuum_full && !state.vacuum_analyze))) {
|
||||||
|
state.buffer_usage_limit = '';
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
helpMessage: gettext('Sizes should be specified as a string containing the numerical size followed by any one of the following memory units: kB (kilobytes), MB (megabytes), GB (gigabytes), or TB (terabytes)'),
|
||||||
|
min_version: 160000,
|
||||||
|
}, {
|
||||||
|
id: 'reindex_system',
|
||||||
|
deps: ['op'],
|
||||||
|
type: 'switch',
|
||||||
|
label: gettext('SYSTEM'),
|
||||||
|
visible: function(state) {
|
||||||
|
return obj.isApplicableForReindex(state);
|
||||||
|
},
|
||||||
|
disabled: function(state) {
|
||||||
|
if (!obj.isApplicableForReindex(state) || obj?._top?.nodeInfo?.schema) {
|
||||||
|
state.reindex_system = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
helpMessage: gettext('This option is enabled only when the database is selected in the object explorer.'),
|
||||||
|
}, {
|
||||||
|
id: 'reindex_concurrently',
|
||||||
|
deps: ['op', 'reindex_system'],
|
||||||
|
type: 'switch',
|
||||||
|
label: gettext('CONCURRENTLY'),
|
||||||
|
visible: function(state) {
|
||||||
|
return obj.isApplicableForReindex(state);
|
||||||
|
},
|
||||||
|
disabled: function(state) {
|
||||||
|
if (!obj.isApplicableForReindex(state) || state.reindex_system) {
|
||||||
|
state.reindex_concurrently = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
min_version: 120000,
|
||||||
|
}, {
|
||||||
|
id: 'reindex_tablespace',
|
||||||
|
label: gettext('TABLESPACE'),
|
||||||
|
deps: ['op', 'reindex_system'],
|
||||||
|
type: 'select',
|
||||||
|
options: this.fieldOptions.tablespace,
|
||||||
|
controlProps: { allowClear: true },
|
||||||
|
visible: function(state) {
|
||||||
|
return obj.isApplicableForReindex(state);
|
||||||
|
},
|
||||||
|
disabled: function(state) {
|
||||||
|
if (!obj.isApplicableForReindex(state) || state.reindex_system) {
|
||||||
|
state.reindex_tablespace = undefined;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
min_version: 140000,
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,11 +327,11 @@ export default class MaintenanceSchema extends BaseUISchema {
|
|||||||
|
|
||||||
constructor(vacuumSchema, fieldOptions = {}) {
|
constructor(vacuumSchema, fieldOptions = {}) {
|
||||||
super({
|
super({
|
||||||
op: 'VACUUM',
|
op: (fieldOptions.nodeInfo?.schema && !fieldOptions.nodeInfo?.table &&
|
||||||
verbose: true,
|
!fieldOptions.nodeInfo?.primary_key && !fieldOptions.nodeInfo?.unique_constraint &&
|
||||||
vacuum_full: false,
|
!fieldOptions.nodeInfo?.index && !fieldOptions.nodeInfo?.partition &&
|
||||||
vacuum_freeze: false,
|
!fieldOptions.nodeInfo?.mview) ? 'REINDEX' : 'VACUUM',
|
||||||
vacuum_analyze: false,
|
verbose: true
|
||||||
});
|
});
|
||||||
|
|
||||||
this.fieldOptions = {
|
this.fieldOptions = {
|
||||||
@ -95,6 +347,12 @@ export default class MaintenanceSchema extends BaseUISchema {
|
|||||||
return 'id';
|
return 'id';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isSchemaNode() {
|
||||||
|
return this.nodeInfo?.schema && !this.nodeInfo?.table &&
|
||||||
|
!this.nodeInfo?.primary_key && !this.nodeInfo?.unique_constraint &&
|
||||||
|
!this.nodeInfo?.index && !this.nodeInfo?.partition;
|
||||||
|
}
|
||||||
|
|
||||||
get baseFields() {
|
get baseFields() {
|
||||||
let obj = this;
|
let obj = this;
|
||||||
return [
|
return [
|
||||||
@ -107,10 +365,12 @@ export default class MaintenanceSchema extends BaseUISchema {
|
|||||||
{
|
{
|
||||||
'label': gettext('VACUUM'),
|
'label': gettext('VACUUM'),
|
||||||
value: 'VACUUM',
|
value: 'VACUUM',
|
||||||
|
disabled: (obj.isSchemaNode() && !obj.nodeInfo?.mview) ? true : false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'label': gettext('ANALYZE'),
|
'label': gettext('ANALYZE'),
|
||||||
value: 'ANALYZE',
|
value: 'ANALYZE',
|
||||||
|
disabled: (obj.isSchemaNode() && !obj.nodeInfo?.mview) ? true : false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'label': gettext('REINDEX'),
|
'label': gettext('REINDEX'),
|
||||||
@ -120,7 +380,7 @@ export default class MaintenanceSchema extends BaseUISchema {
|
|||||||
{
|
{
|
||||||
'label': gettext('CLUSTER'),
|
'label': gettext('CLUSTER'),
|
||||||
value: 'CLUSTER',
|
value: 'CLUSTER',
|
||||||
disabled: obj.nodeInfo?.mview?true:false
|
disabled: obj.nodeInfo?.mview ? true : obj.isSchemaNode() ? true : false
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -129,6 +389,14 @@ export default class MaintenanceSchema extends BaseUISchema {
|
|||||||
label: gettext('Type of objects'),
|
label: gettext('Type of objects'),
|
||||||
schema: obj.getVacuumSchema(),
|
schema: obj.getVacuumSchema(),
|
||||||
group: gettext('Options'),
|
group: gettext('Options'),
|
||||||
|
visible: function(state) {
|
||||||
|
if (state?.op == 'ANALYZE') {
|
||||||
|
return obj?.nodeInfo?.server?.version >= 120000;
|
||||||
|
} else if (state?.op == 'CLUSTER') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'verbose',
|
id: 'verbose',
|
||||||
@ -136,21 +404,6 @@ export default class MaintenanceSchema extends BaseUISchema {
|
|||||||
deps: ['op'],
|
deps: ['op'],
|
||||||
type: 'switch',
|
type: 'switch',
|
||||||
label: gettext('Verbose Messages'),
|
label: gettext('Verbose Messages'),
|
||||||
disabled: function(state) {
|
|
||||||
let nodeInfo = this.nodeInfo;
|
|
||||||
if(state?.verbose) {
|
|
||||||
if ('primary_key' in nodeInfo || 'unique_constraint' in nodeInfo ||
|
|
||||||
'index' in nodeInfo) {
|
|
||||||
if (state.op == 'REINDEX') {
|
|
||||||
state.verbose = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return state.op == 'REINDEX';
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,6 @@
|
|||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
export const maintenanceSupportedNodes = [
|
export const maintenanceSupportedNodes = [
|
||||||
'database', 'table', 'primary_key',
|
'database', 'schema', 'table', 'primary_key',
|
||||||
'unique_constraint', 'index', 'partition',
|
'unique_constraint', 'index', 'partition', 'mview'
|
||||||
];
|
];
|
||||||
|
@ -1,14 +1,31 @@
|
|||||||
|
{% set maintenance_options = [] %}
|
||||||
|
{% if data.verbose %}{{ maintenance_options.append('VERBOSE') or "" }}{% endif %}
|
||||||
|
{% if data.vacuum_full %}{{ maintenance_options.append('FULL') or "" }}{% endif %}
|
||||||
|
{% if data.vacuum_freeze %}{{ maintenance_options.append('FREEZE') or "" }}{% endif %}
|
||||||
|
{% if data.vacuum_analyze %}{{ maintenance_options.append('ANALYZE') or "" }}{% endif %}
|
||||||
|
{% if data.vacuum_disable_page_skipping %}{{ maintenance_options.append('DISABLE_PAGE_SKIPPING') or "" }}{% endif %}
|
||||||
|
{% if data.skip_locked %}{{ maintenance_options.append('SKIP_LOCKED') or "" }}{% endif %}
|
||||||
|
{% if data.vacuum_truncate %}{{ maintenance_options.append('TRUNCATE') or "" }}{% endif %}
|
||||||
|
{% if data.vacuum_process_toast %}{{ maintenance_options.append('PROCESS_TOAST') or "" }}{% endif %}
|
||||||
|
{% if data.vacuum_process_main %}{{ maintenance_options.append('PROCESS_MAIN') or "" }}{% endif %}
|
||||||
|
{% if data.vacuum_skip_database_stats %}{{ maintenance_options.append('SKIP_DATABASE_STATS') or "" }}{% endif %}
|
||||||
|
{% if data.vacuum_only_database_stats %}{{ maintenance_options.append('ONLY_DATABASE_STATS') or "" }}{% endif %}
|
||||||
|
{% if data.vacuum_index_cleanup %}{{ maintenance_options.append('INDEX_CLEANUP ' + data.vacuum_index_cleanup) or "" }}{% endif %}
|
||||||
|
{% if data.vacuum_parallel %}{{ maintenance_options.append('PARALLEL ' + data.vacuum_parallel) or "" }}{% endif %}
|
||||||
|
{% if data.buffer_usage_limit %}{{ maintenance_options.append('BUFFER_USAGE_LIMIT "' + data.buffer_usage_limit + '"') or "" }}{% endif %}
|
||||||
|
{% if data.reindex_tablespace %}{{ maintenance_options.append('TABLESPACE "' + data.reindex_tablespace + '"') or "" }}{% endif %}
|
||||||
|
{% if data.reindex_concurrently %}{{ maintenance_options.append('CONCURRENTLY') or "" }}{% endif %}
|
||||||
{% if data.op == "VACUUM" %}
|
{% if data.op == "VACUUM" %}
|
||||||
VACUUM{% if data.vacuum_full %} FULL{% endif %}{% if data.vacuum_freeze %} FREEZE{% endif %}{% if data.verbose %} VERBOSE{% endif %}{% if data.vacuum_analyze %} ANALYZE{% endif %}{% if data.schema %} {{ conn|qtIdent(data.schema) }}.{{ conn|qtIdent(data.table) }}{% endif %};
|
VACUUM{% for option in maintenance_options %}{% if loop.first %} ({% endif %}{{ option }}{% if not loop.last %}, {% endif %}{% if loop.last %}){% endif %}{% endfor %}{% if data.schema %} {{ conn|qtIdent(data.schema) }}.{{ conn|qtIdent(data.table) }}{% endif %};
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if data.op == "ANALYZE" %}
|
{% if data.op == "ANALYZE" %}
|
||||||
ANALYZE{% if data.verbose %} VERBOSE{% endif %}{% if data.schema %} {{ conn|qtIdent(data.schema, data.table) }}{% endif %};
|
ANALYZE{% for option in maintenance_options %}{% if loop.first %} ({% endif %}{{ option }}{% if not loop.last %}, {% endif %}{% if loop.last %}){% endif %}{% endfor %}{% if data.schema %} {{ conn|qtIdent(data.schema, data.table) }}{% endif %};
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if data.op == "REINDEX" %}
|
{% if data.op == "REINDEX" %}
|
||||||
{% if index_name %}
|
{% if index_name %}
|
||||||
REINDEX INDEX {{ conn|qtIdent(data.schema, index_name) }};
|
REINDEX{% for option in maintenance_options %}{% if loop.first %} ({% endif %}{{ option }}{% if not loop.last %}, {% endif %}{% if loop.last %}){% endif %}{% endfor %} INDEX {{ conn|qtIdent(data.schema, index_name) }};
|
||||||
{% else %}
|
{% else %}
|
||||||
REINDEX{% if not data.schema %} DATABASE {{ conn|qtIdent(data.database) }}{% else %} TABLE {{ conn|qtIdent(data.schema, data.table) }}{% endif %};
|
REINDEX{% for option in maintenance_options %}{% if loop.first %} ({% endif %}{{ option }}{% if not loop.last %}, {% endif %}{% if loop.last %}){% endif %}{% endfor %}{% if not data.schema and not data.reindex_system %} DATABASE {{ conn|qtIdent(data.database) }}{% elif not data.schema and data.reindex_system%} SYSTEM {{ conn|qtIdent(data.database) }}{% elif data.schema and not data.table and not data.primary_key and not data.unique_constraint and not data.index and not data.mview %} SCHEMA {{ conn|qtIdent(data.schema) }}{% else %} TABLE {{ conn|qtIdent(data.schema, data.table) }}{% endif %};
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if data.op == "CLUSTER" %}
|
{% if data.op == "CLUSTER" %}
|
||||||
|
@ -53,8 +53,8 @@ class BatchProcessTest(BaseTestGenerator):
|
|||||||
},
|
},
|
||||||
cmd="VACUUM VERBOSE;\n"
|
cmd="VACUUM VERBOSE;\n"
|
||||||
),
|
),
|
||||||
expected_msg="VACUUM (VERBOSE) on database "
|
expected_msg="VACUUM on database 'postgres' of server " +
|
||||||
"'postgres' of server " + SERVER_NAME,
|
SERVER_NAME,
|
||||||
expected_details_cmd='VACUUM VERBOSE;'
|
expected_details_cmd='VACUUM VERBOSE;'
|
||||||
))
|
))
|
||||||
]
|
]
|
||||||
|
@ -34,7 +34,7 @@ class MaintenanceJobTest(BaseTestGenerator):
|
|||||||
cmd="VACUUM VERBOSE;\n"
|
cmd="VACUUM VERBOSE;\n"
|
||||||
),
|
),
|
||||||
url='/maintenance/job/{0}/{1}',
|
url='/maintenance/job/{0}/{1}',
|
||||||
expected_cmd='VACUUM VERBOSE',
|
expected_cmd='VACUUM (VERBOSE)',
|
||||||
expected_exit_code=[0, None]
|
expected_exit_code=[0, None]
|
||||||
))
|
))
|
||||||
]
|
]
|
||||||
|
@ -19,6 +19,8 @@ from unittest.mock import patch, MagicMock
|
|||||||
|
|
||||||
from config import PG_DEFAULT_DRIVER
|
from config import PG_DEFAULT_DRIVER
|
||||||
|
|
||||||
|
MAINTENANCE_URL = '/maintenance/job/{0}/{1}'
|
||||||
|
|
||||||
|
|
||||||
class MaintenanceCreateJobTest(BaseTestGenerator):
|
class MaintenanceCreateJobTest(BaseTestGenerator):
|
||||||
"""Test the BackupCreateJob class"""
|
"""Test the BackupCreateJob class"""
|
||||||
@ -40,10 +42,11 @@ class MaintenanceCreateJobTest(BaseTestGenerator):
|
|||||||
vacuum_full=False,
|
vacuum_full=False,
|
||||||
verbose=True
|
verbose=True
|
||||||
),
|
),
|
||||||
url='/maintenance/job/{0}/{1}',
|
url=MAINTENANCE_URL,
|
||||||
expected_cmd_opts=['VACUUM VERBOSE;\n'],
|
expected_cmd_opts=['VACUUM (VERBOSE);\n'],
|
||||||
)),
|
)),
|
||||||
('When maintaining object with VACUUM FULL',
|
('When maintaining object with VACUUM FULL, FREEZE, ANALYZE, '
|
||||||
|
'DISABLE_PAGE_SKIPPING',
|
||||||
dict(
|
dict(
|
||||||
class_params=dict(
|
class_params=dict(
|
||||||
sid=1,
|
sid=1,
|
||||||
@ -55,13 +58,130 @@ class MaintenanceCreateJobTest(BaseTestGenerator):
|
|||||||
params=dict(
|
params=dict(
|
||||||
database='postgres',
|
database='postgres',
|
||||||
op='VACUUM',
|
op='VACUUM',
|
||||||
vacuum_analyze=False,
|
vacuum_analyze=True,
|
||||||
vacuum_freeze=False,
|
vacuum_freeze=True,
|
||||||
vacuum_full=True,
|
vacuum_full=True,
|
||||||
|
vacuum_disable_page_skipping=True,
|
||||||
verbose=True
|
verbose=True
|
||||||
),
|
),
|
||||||
url='/maintenance/job/{0}/{1}',
|
url=MAINTENANCE_URL,
|
||||||
expected_cmd_opts=['VACUUM FULL VERBOSE;\n'],
|
expected_cmd_opts=['VACUUM (VERBOSE, FULL, FREEZE, ANALYZE, '
|
||||||
|
'DISABLE_PAGE_SKIPPING);\n'],
|
||||||
|
)),
|
||||||
|
('When maintaining object with VACUUM SKIP LOCKED, TRUNCATE, '
|
||||||
|
'INDEX CLEANUP',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
op='VACUUM',
|
||||||
|
skip_locked=True,
|
||||||
|
vacuum_truncate=True,
|
||||||
|
vacuum_index_cleanup='OFF',
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['VACUUM (VERBOSE, SKIP_LOCKED, TRUNCATE, '
|
||||||
|
'INDEX_CLEANUP OFF);\n'],
|
||||||
|
server_min_version=120000,
|
||||||
|
message='VACUUM SKIP_LOCKED, TRUNCATE and INDEX_CLEANUP is not '
|
||||||
|
'supported by EPAS/PG server less than 12.0'
|
||||||
|
)),
|
||||||
|
('When maintaining object with VACUUM PARALLEL',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
op='VACUUM',
|
||||||
|
vacuum_parallel='15',
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['VACUUM (VERBOSE, PARALLEL 15);\n'],
|
||||||
|
server_min_version=130000,
|
||||||
|
message='VACUUM PARALLEL is not supported by EPAS/PG server '
|
||||||
|
'less than 13.0'
|
||||||
|
)),
|
||||||
|
('When maintaining object with VACUUM PROCESS TOAST',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
op='VACUUM',
|
||||||
|
vacuum_process_toast=True,
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['VACUUM (VERBOSE, PROCESS_TOAST);\n'],
|
||||||
|
server_min_version=140000,
|
||||||
|
message='VACUUM PROCESS TOAST is not supported by EPAS/PG server '
|
||||||
|
'less than 14.0'
|
||||||
|
)),
|
||||||
|
('When maintaining object with VACUUM SKIP DATABASE STATS, '
|
||||||
|
'PROCESS MAIN, BUFFER USAGE LIMIT',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
op='VACUUM',
|
||||||
|
vacuum_process_main=True,
|
||||||
|
vacuum_skip_database_stats=True,
|
||||||
|
buffer_usage_limit='1MB',
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['VACUUM (VERBOSE, PROCESS_MAIN, '
|
||||||
|
'SKIP_DATABASE_STATS, BUFFER_USAGE_LIMIT "1MB"'
|
||||||
|
');\n'],
|
||||||
|
server_min_version=160000,
|
||||||
|
message='VACUUM SKIP_DATABASE_STATS, PROCESS_MAIN and '
|
||||||
|
'BUFFER_USAGE_LIMIT is not supported by EPAS/PG server '
|
||||||
|
'less than 16.0'
|
||||||
|
)),
|
||||||
|
('When maintaining object with VACUUM ONLY DATABASE STATS',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
op='VACUUM',
|
||||||
|
vacuum_only_database_stats=True,
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['VACUUM (VERBOSE, ONLY_DATABASE_STATS);\n'],
|
||||||
|
server_min_version=160000,
|
||||||
|
message='VACUUM ONLY DATABASE STATS is not supported by EPAS/PG '
|
||||||
|
'server less than 16.0'
|
||||||
)),
|
)),
|
||||||
('When maintaining object with ANALYZE',
|
('When maintaining object with ANALYZE',
|
||||||
dict(
|
dict(
|
||||||
@ -75,13 +195,314 @@ class MaintenanceCreateJobTest(BaseTestGenerator):
|
|||||||
params=dict(
|
params=dict(
|
||||||
database='postgres',
|
database='postgres',
|
||||||
op='ANALYZE',
|
op='ANALYZE',
|
||||||
vacuum_analyze=True,
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['ANALYZE (VERBOSE);\n'],
|
||||||
|
)),
|
||||||
|
('When maintaining object with ANALYZE SKIP LOCKED',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
op='ANALYZE',
|
||||||
|
skip_locked=True,
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['ANALYZE (VERBOSE, SKIP_LOCKED);\n'],
|
||||||
|
server_min_version=120000,
|
||||||
|
message='ANALYZE SKIP_LOCKED is not supported by EPAS/PG server '
|
||||||
|
'less than 12.0'
|
||||||
|
)),
|
||||||
|
('When maintaining object with ANALYZE BUFFER USAGE LIMIT',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
op='ANALYZE',
|
||||||
|
buffer_usage_limit='1MB',
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['ANALYZE (VERBOSE, BUFFER_USAGE_LIMIT "1MB"'
|
||||||
|
');\n'],
|
||||||
|
server_min_version=160000,
|
||||||
|
message='ANALYZE BUFFER_USAGE_LIMIT is not supported by '
|
||||||
|
'EPAS/PG server less than 16.0'
|
||||||
|
)),
|
||||||
|
('When maintaining object with default options on table',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
op='VACUUM',
|
||||||
|
schema='my_schema',
|
||||||
|
table='my_table',
|
||||||
|
vacuum_analyze=False,
|
||||||
vacuum_freeze=False,
|
vacuum_freeze=False,
|
||||||
vacuum_full=False,
|
vacuum_full=False,
|
||||||
verbose=True
|
verbose=True
|
||||||
),
|
),
|
||||||
url='/maintenance/job/{0}/{1}',
|
url=MAINTENANCE_URL,
|
||||||
expected_cmd_opts=['ANALYZE VERBOSE;\n'],
|
expected_cmd_opts=['VACUUM (VERBOSE) my_schema.my_table;\n'],
|
||||||
|
)),
|
||||||
|
('When maintaining object with VACUUM FULL, FREEZE, ANALYZE, '
|
||||||
|
'DISABLE_PAGE_SKIPPING on table',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
op='VACUUM',
|
||||||
|
schema='my_schema',
|
||||||
|
table='my_table',
|
||||||
|
vacuum_analyze=True,
|
||||||
|
vacuum_freeze=True,
|
||||||
|
vacuum_full=True,
|
||||||
|
vacuum_disable_page_skipping=True,
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['VACUUM (VERBOSE, FULL, FREEZE, ANALYZE, '
|
||||||
|
'DISABLE_PAGE_SKIPPING) my_schema.my_table'
|
||||||
|
';\n'],
|
||||||
|
)),
|
||||||
|
('When maintaining object with VACUUM SKIP LOCKED, TRUNCATE, '
|
||||||
|
'INDEX CLEANUP on table',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
op='VACUUM',
|
||||||
|
schema='my_schema',
|
||||||
|
table='my_table',
|
||||||
|
skip_locked=True,
|
||||||
|
vacuum_truncate=True,
|
||||||
|
vacuum_index_cleanup='OFF',
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['VACUUM (VERBOSE, SKIP_LOCKED, TRUNCATE, '
|
||||||
|
'INDEX_CLEANUP OFF) my_schema.my_table;\n'],
|
||||||
|
server_min_version=120000,
|
||||||
|
message='VACUUM SKIP_LOCKED, TRUNCATE and INDEX_CLEANUP is not '
|
||||||
|
'supported by EPAS/PG server less than 12.0'
|
||||||
|
)),
|
||||||
|
('When maintaining object with VACUUM PARALLEL on table',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
op='VACUUM',
|
||||||
|
schema='my_schema',
|
||||||
|
table='my_table',
|
||||||
|
vacuum_parallel='15',
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['VACUUM (VERBOSE, PARALLEL 15) '
|
||||||
|
'my_schema.my_table;\n'],
|
||||||
|
server_min_version=130000,
|
||||||
|
message='VACUUM PARALLEL is not supported by EPAS/PG server '
|
||||||
|
'less than 13.0'
|
||||||
|
)),
|
||||||
|
('When maintaining object with VACUUM PROCESS TOAST on table',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
op='VACUUM',
|
||||||
|
schema='my_schema',
|
||||||
|
table='my_table',
|
||||||
|
vacuum_process_toast=True,
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['VACUUM (VERBOSE, PROCESS_TOAST) '
|
||||||
|
'my_schema.my_table;\n'],
|
||||||
|
server_min_version=140000,
|
||||||
|
message='VACUUM PROCESS TOAST is not supported by EPAS/PG server '
|
||||||
|
'less than 14.0'
|
||||||
|
)),
|
||||||
|
('When maintaining object with VACUUM SKIP DATABASE STATS, '
|
||||||
|
'PROCESS MAIN, BUFFER USAGE LIMIT on table',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
op='VACUUM',
|
||||||
|
schema='my_schema',
|
||||||
|
table='my_table',
|
||||||
|
vacuum_process_main=True,
|
||||||
|
vacuum_skip_database_stats=True,
|
||||||
|
buffer_usage_limit='1MB',
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['VACUUM (VERBOSE, PROCESS_MAIN, '
|
||||||
|
'SKIP_DATABASE_STATS, BUFFER_USAGE_LIMIT "1MB"'
|
||||||
|
') my_schema.my_table;\n'],
|
||||||
|
server_min_version=160000,
|
||||||
|
message='VACUUM SKIP_DATABASE_STATS, PROCESS_MAIN and '
|
||||||
|
'BUFFER_USAGE_LIMIT is not supported by EPAS/PG server '
|
||||||
|
'less than 16.0'
|
||||||
|
)),
|
||||||
|
('When maintaining object with VACUUM ONLY DATABASE STATS on table',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
op='VACUUM',
|
||||||
|
schema='my_schema',
|
||||||
|
table='my_table',
|
||||||
|
vacuum_only_database_stats=True,
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['VACUUM (VERBOSE, ONLY_DATABASE_STATS) '
|
||||||
|
'my_schema.my_table;\n'],
|
||||||
|
server_min_version=160000,
|
||||||
|
message='VACUUM ONLY DATABASE STATS is not supported by EPAS/PG '
|
||||||
|
'server less than 16.0'
|
||||||
|
)),
|
||||||
|
('When maintaining object with ANALYZE on table',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
op='ANALYZE',
|
||||||
|
schema='my_schema',
|
||||||
|
table='my_table',
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['ANALYZE (VERBOSE) my_schema.my_table;\n'],
|
||||||
|
)),
|
||||||
|
('When maintaining object with ANALYZE SKIP LOCKED on table',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
op='ANALYZE',
|
||||||
|
schema='my_schema',
|
||||||
|
table='my_table',
|
||||||
|
skip_locked=True,
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['ANALYZE (VERBOSE, SKIP_LOCKED) '
|
||||||
|
'my_schema.my_table;\n'],
|
||||||
|
server_min_version=120000,
|
||||||
|
message='ANALYZE SKIP_LOCKED is not supported by EPAS/PG server '
|
||||||
|
'less than 12.0'
|
||||||
|
)),
|
||||||
|
('When maintaining object with ANALYZE BUFFER USAGE LIMIT on table',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
op='ANALYZE',
|
||||||
|
schema='my_schema',
|
||||||
|
table='my_table',
|
||||||
|
buffer_usage_limit='1MB',
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['ANALYZE (VERBOSE, BUFFER_USAGE_LIMIT "1MB"'
|
||||||
|
') my_schema.my_table;\n'],
|
||||||
|
server_min_version=160000,
|
||||||
|
message='ANALYZE BUFFER_USAGE_LIMIT is not supported by '
|
||||||
|
'EPAS/PG server less than 16.0'
|
||||||
|
)),
|
||||||
|
('When maintenance the object with the REINDEX SYSTEM',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
op='REINDEX',
|
||||||
|
reindex_system=True,
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['REINDEX (VERBOSE) SYSTEM postgres;\n'],
|
||||||
)),
|
)),
|
||||||
('When maintenance the object with the REINDEX',
|
('When maintenance the object with the REINDEX',
|
||||||
dict(
|
dict(
|
||||||
@ -95,14 +516,207 @@ class MaintenanceCreateJobTest(BaseTestGenerator):
|
|||||||
params=dict(
|
params=dict(
|
||||||
database='postgres',
|
database='postgres',
|
||||||
op='REINDEX',
|
op='REINDEX',
|
||||||
vacuum_analyze=False,
|
|
||||||
vacuum_freeze=False,
|
|
||||||
vacuum_full=False,
|
|
||||||
verbose=False
|
verbose=False
|
||||||
),
|
),
|
||||||
url='/maintenance/job/{0}/{1}',
|
url=MAINTENANCE_URL,
|
||||||
expected_cmd_opts=['REINDEX DATABASE postgres;\n'],
|
expected_cmd_opts=['REINDEX DATABASE postgres;\n'],
|
||||||
)),
|
)),
|
||||||
|
('When maintenance the object with the REINDEX CONCURRENTLY',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
op='REINDEX',
|
||||||
|
reindex_concurrently=True,
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['REINDEX (VERBOSE, CONCURRENTLY) DATABASE '
|
||||||
|
'postgres;\n'],
|
||||||
|
server_min_version=120000,
|
||||||
|
message='REINDEX CONCURRENTLY is not supported by EPAS/PG server '
|
||||||
|
'less than 12.0'
|
||||||
|
)),
|
||||||
|
('When maintenance the object with the REINDEX TABLESPACE',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
op='REINDEX',
|
||||||
|
reindex_tablespace='pg_default',
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['REINDEX (VERBOSE, TABLESPACE "pg_default") '
|
||||||
|
'DATABASE postgres;\n'],
|
||||||
|
server_min_version=140000,
|
||||||
|
message='REINDEX TABLESPACE is not supported by EPAS/PG server '
|
||||||
|
'less than 14.0'
|
||||||
|
)),
|
||||||
|
('When maintenance the object with the REINDEX SCHEMA',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
schema='my_schema',
|
||||||
|
op='REINDEX',
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['REINDEX (VERBOSE) SCHEMA my_schema;\n'],
|
||||||
|
)),
|
||||||
|
('When maintenance the object with the REINDEX TABLE',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
schema='my_schema',
|
||||||
|
table='my_table',
|
||||||
|
op='REINDEX',
|
||||||
|
verbose=False
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['REINDEX TABLE my_schema.my_table;\n'],
|
||||||
|
)),
|
||||||
|
('When maintenance the object with the REINDEX CONCURRENTLY TABLE',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
schema='my_schema',
|
||||||
|
table='my_table',
|
||||||
|
op='REINDEX',
|
||||||
|
reindex_concurrently=True,
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['REINDEX (VERBOSE, CONCURRENTLY) TABLE '
|
||||||
|
'my_schema.my_table;\n'],
|
||||||
|
server_min_version=120000,
|
||||||
|
message='REINDEX CONCURRENTLY TABLE is not supported by '
|
||||||
|
'EPAS/PG server less than 12.0'
|
||||||
|
)),
|
||||||
|
('When maintenance the object with the REINDEX TABLESPACE TABLE',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
schema='my_schema',
|
||||||
|
table='my_table',
|
||||||
|
op='REINDEX',
|
||||||
|
reindex_tablespace='pg_default',
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['REINDEX (VERBOSE, TABLESPACE "pg_default") '
|
||||||
|
'TABLE my_schema.my_table;\n'],
|
||||||
|
server_min_version=140000,
|
||||||
|
message='REINDEX TABLESPACE TABLE is not supported by '
|
||||||
|
'EPAS/PG server less than 14.0'
|
||||||
|
)),
|
||||||
|
('When maintenance the object with the REINDEX INDEX',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
schema='my_schema',
|
||||||
|
index='my_index',
|
||||||
|
op='REINDEX',
|
||||||
|
verbose=False
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['REINDEX INDEX my_schema.my_index;\n'],
|
||||||
|
)),
|
||||||
|
('When maintenance the object with the REINDEX CONCURRENTLY INDEX',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
schema='my_schema',
|
||||||
|
index='my_index',
|
||||||
|
op='REINDEX',
|
||||||
|
reindex_concurrently=True,
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['REINDEX (VERBOSE, CONCURRENTLY) INDEX '
|
||||||
|
'my_schema.my_index;\n'],
|
||||||
|
server_min_version=120000,
|
||||||
|
message='REINDEX CONCURRENTLY is not supported by EPAS/PG server '
|
||||||
|
'less than 12.0'
|
||||||
|
)),
|
||||||
|
('When maintenance the object with the REINDEX TABLESPACE INDEX',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
schema='my_schema',
|
||||||
|
index='my_index',
|
||||||
|
op='REINDEX',
|
||||||
|
reindex_tablespace='pg_default',
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['REINDEX (VERBOSE, TABLESPACE "pg_default") '
|
||||||
|
'INDEX my_schema.my_index;\n'],
|
||||||
|
server_min_version=140000,
|
||||||
|
message='REINDEX TABLESPACE is not supported by EPAS/PG server '
|
||||||
|
'less than 14.0'
|
||||||
|
)),
|
||||||
('When maintenance the object with the CLUSTER',
|
('When maintenance the object with the CLUSTER',
|
||||||
dict(
|
dict(
|
||||||
class_params=dict(
|
class_params=dict(
|
||||||
@ -115,13 +729,50 @@ class MaintenanceCreateJobTest(BaseTestGenerator):
|
|||||||
params=dict(
|
params=dict(
|
||||||
database='postgres',
|
database='postgres',
|
||||||
op='CLUSTER',
|
op='CLUSTER',
|
||||||
vacuum_analyze=False,
|
verbose=True
|
||||||
vacuum_freeze=False,
|
|
||||||
vacuum_full=False,
|
|
||||||
verbose=False
|
|
||||||
),
|
),
|
||||||
url='/maintenance/job/{0}/{1}',
|
url=MAINTENANCE_URL,
|
||||||
expected_cmd_opts=['CLUSTER;\n'],
|
expected_cmd_opts=['CLUSTER VERBOSE;\n'],
|
||||||
|
)),
|
||||||
|
('When maintenance the object with the CLUSTER on table',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
schema='my_schema',
|
||||||
|
table='my_table',
|
||||||
|
op='CLUSTER',
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['CLUSTER VERBOSE my_schema.my_table;\n'],
|
||||||
|
)),
|
||||||
|
('When maintenance the object with the CLUSTER on table using index',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
name='test_maintenance_server',
|
||||||
|
port=5444,
|
||||||
|
host='localhost',
|
||||||
|
username='postgres'
|
||||||
|
),
|
||||||
|
params=dict(
|
||||||
|
database='postgres',
|
||||||
|
schema='my_schema',
|
||||||
|
table='my_table',
|
||||||
|
index='my_index',
|
||||||
|
op='CLUSTER',
|
||||||
|
verbose=True
|
||||||
|
),
|
||||||
|
url=MAINTENANCE_URL,
|
||||||
|
expected_cmd_opts=['CLUSTER VERBOSE my_schema.my_table '
|
||||||
|
'USING my_index;\n'],
|
||||||
))
|
))
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -142,9 +793,9 @@ class MaintenanceCreateJobTest(BaseTestGenerator):
|
|||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
binary_path = binary_path + '.exe'
|
binary_path = binary_path + '.exe'
|
||||||
|
|
||||||
retVal = does_utility_exist(binary_path)
|
ret_val = does_utility_exist(binary_path)
|
||||||
if retVal is not None:
|
if ret_val is not None:
|
||||||
self.skipTest(retVal)
|
self.skipTest(ret_val)
|
||||||
|
|
||||||
@patch('pgadmin.tools.maintenance.Server')
|
@patch('pgadmin.tools.maintenance.Server')
|
||||||
@patch('pgadmin.tools.maintenance.Message')
|
@patch('pgadmin.tools.maintenance.Message')
|
||||||
@ -189,6 +840,11 @@ class MaintenanceCreateJobTest(BaseTestGenerator):
|
|||||||
self.data = database_utils.get_db_data(db_owner)
|
self.data = database_utils.get_db_data(db_owner)
|
||||||
self.db_name = self.data['name']
|
self.db_name = self.data['name']
|
||||||
|
|
||||||
|
if hasattr(self, 'server_min_version') and \
|
||||||
|
server_response["data"]["version"] < \
|
||||||
|
self.server_min_version:
|
||||||
|
self.skipTest(self.message)
|
||||||
|
|
||||||
# Create the backup job
|
# Create the backup job
|
||||||
response = self.tester.post(url,
|
response = self.tester.post(url,
|
||||||
data=json.dumps(self.params),
|
data=json.dumps(self.params),
|
||||||
|
@ -17,7 +17,7 @@ class MaintenanceMessageTest(BaseTestGenerator):
|
|||||||
|
|
||||||
SERVER_NAME = "server (host:port)"
|
SERVER_NAME = "server (host:port)"
|
||||||
scenarios = [
|
scenarios = [
|
||||||
('When maintained the server',
|
('When maintained the server with VACUUM on database',
|
||||||
dict(
|
dict(
|
||||||
class_params=dict(
|
class_params=dict(
|
||||||
sid=1,
|
sid=1,
|
||||||
@ -31,67 +31,190 @@ class MaintenanceMessageTest(BaseTestGenerator):
|
|||||||
},
|
},
|
||||||
cmd="VACUUM VERBOSE;\n"
|
cmd="VACUUM VERBOSE;\n"
|
||||||
),
|
),
|
||||||
expected_msg="VACUUM (VERBOSE) on database "
|
expected_msg="VACUUM on database 'postgres' of server " +
|
||||||
"'postgres' of server " + SERVER_NAME,
|
SERVER_NAME
|
||||||
expected_details_cmd='VACUUM VERBOSE;'
|
|
||||||
|
|
||||||
)),
|
)),
|
||||||
('When maintained the server with FULL VERBOSE options',
|
('When maintained the server with VACUUM on table ',
|
||||||
dict(
|
dict(
|
||||||
class_params=dict(
|
class_params=dict(
|
||||||
sid=1,
|
sid=1,
|
||||||
data={
|
data={
|
||||||
'database': 'postgres',
|
'database': 'postgres',
|
||||||
|
'schema': 'test_schema',
|
||||||
|
'table': 'test_table',
|
||||||
|
'op': 'VACUUM',
|
||||||
|
'verbose': True
|
||||||
|
},
|
||||||
|
cmd="VACUUM FULL;\n"
|
||||||
|
),
|
||||||
|
expected_msg="VACUUM on table 'postgres/test_schema/test_table' "
|
||||||
|
"of server " + SERVER_NAME
|
||||||
|
)),
|
||||||
|
('When maintained the server with VACUUM on constraint ',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
data={
|
||||||
|
'database': 'postgres',
|
||||||
|
'schema': 'test_schema',
|
||||||
|
'table': 'test_table',
|
||||||
|
'primary_key': 'test_pkey',
|
||||||
'op': 'VACUUM',
|
'op': 'VACUUM',
|
||||||
'vacuum_analyze': False,
|
|
||||||
'vacuum_freeze': False,
|
|
||||||
'vacuum_full': True,
|
|
||||||
'verbose': True
|
'verbose': True
|
||||||
},
|
},
|
||||||
cmd="VACUUM FULL VERBOSE;\n"
|
cmd="VACUUM FULL VERBOSE;\n"
|
||||||
),
|
),
|
||||||
expected_msg="VACUUM (FULL, VERBOSE) on database "
|
expected_msg="VACUUM on constraint "
|
||||||
"'postgres' of server " + SERVER_NAME,
|
"'postgres/test_schema/test_table/test_pkey' "
|
||||||
expected_details_cmd='VACUUM FULL VERBOSE;'
|
"of server " + SERVER_NAME
|
||||||
|
|
||||||
)),
|
)),
|
||||||
('When maintained the server with ANALYZE',
|
('When maintained the server with VACUUM on index ',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
data={
|
||||||
|
'database': 'postgres',
|
||||||
|
'schema': 'test_schema',
|
||||||
|
'table': 'test_table',
|
||||||
|
'index': 'test_idx',
|
||||||
|
'op': 'VACUUM',
|
||||||
|
'verbose': True
|
||||||
|
},
|
||||||
|
cmd="VACUUM FULL VERBOSE;\n"
|
||||||
|
),
|
||||||
|
expected_msg="VACUUM on index "
|
||||||
|
"'postgres/test_schema/test_table/test_idx' "
|
||||||
|
"of server " + SERVER_NAME
|
||||||
|
)),
|
||||||
|
('When maintained the server with ANALYZE on database',
|
||||||
dict(
|
dict(
|
||||||
class_params=dict(
|
class_params=dict(
|
||||||
sid=1,
|
sid=1,
|
||||||
data={
|
data={
|
||||||
'database': 'postgres',
|
'database': 'postgres',
|
||||||
'op': 'ANALYZE',
|
'op': 'ANALYZE',
|
||||||
'vacuum_analyze': False,
|
|
||||||
'vacuum_freeze': False,
|
|
||||||
'vacuum_full': False,
|
|
||||||
'verbose': True
|
'verbose': True
|
||||||
},
|
},
|
||||||
cmd="ANALYZE VERBOSE;\n"
|
cmd="ANALYZE VERBOSE;\n"
|
||||||
),
|
),
|
||||||
expected_msg="ANALYZE(VERBOSE) on database "
|
expected_msg="ANALYZE on database 'postgres' of server " +
|
||||||
"'postgres' of server " + SERVER_NAME,
|
SERVER_NAME
|
||||||
expected_details_cmd='ANALYZE VERBOSE;'
|
|
||||||
|
|
||||||
)),
|
)),
|
||||||
('When maintained the server with REINDEX',
|
('When maintained the server with ANALYZE on table ',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
data={
|
||||||
|
'database': 'postgres',
|
||||||
|
'schema': 'test_schema',
|
||||||
|
'table': 'test_table',
|
||||||
|
'op': 'ANALYZE',
|
||||||
|
'verbose': True
|
||||||
|
},
|
||||||
|
cmd="ANALYZE VERBOSE;\n"
|
||||||
|
),
|
||||||
|
expected_msg="ANALYZE on table 'postgres/test_schema/test_table' "
|
||||||
|
"of server " + SERVER_NAME
|
||||||
|
)),
|
||||||
|
('When maintained the server with ANALYZE on constraint ',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
data={
|
||||||
|
'database': 'postgres',
|
||||||
|
'schema': 'test_schema',
|
||||||
|
'table': 'test_table',
|
||||||
|
'primary_key': 'test_pkey',
|
||||||
|
'op': 'ANALYZE',
|
||||||
|
'verbose': True
|
||||||
|
},
|
||||||
|
cmd="ANALYZE FULL VERBOSE;\n"
|
||||||
|
),
|
||||||
|
expected_msg="ANALYZE on constraint "
|
||||||
|
"'postgres/test_schema/test_table/test_pkey' "
|
||||||
|
"of server " + SERVER_NAME
|
||||||
|
)),
|
||||||
|
('When maintained the server with ANALYZE on index ',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
data={
|
||||||
|
'database': 'postgres',
|
||||||
|
'schema': 'test_schema',
|
||||||
|
'table': 'test_table',
|
||||||
|
'index': 'test_idx',
|
||||||
|
'op': 'ANALYZE',
|
||||||
|
'verbose': True
|
||||||
|
},
|
||||||
|
cmd="ANALYZE;\n"
|
||||||
|
),
|
||||||
|
expected_msg="ANALYZE on index "
|
||||||
|
"'postgres/test_schema/test_table/test_idx' "
|
||||||
|
"of server " + SERVER_NAME
|
||||||
|
)),
|
||||||
|
('When maintained the server with REINDEX on database',
|
||||||
dict(
|
dict(
|
||||||
class_params=dict(
|
class_params=dict(
|
||||||
sid=1,
|
sid=1,
|
||||||
data={
|
data={
|
||||||
'database': 'postgres',
|
'database': 'postgres',
|
||||||
'op': 'REINDEX',
|
'op': 'REINDEX',
|
||||||
'vacuum_analyze': False,
|
'verbose': False
|
||||||
'vacuum_freeze': False,
|
},
|
||||||
'vacuum_full': False,
|
cmd="REINDEX (VERBOSE);\n"
|
||||||
|
),
|
||||||
|
expected_msg="REINDEX on database 'postgres' of server " +
|
||||||
|
SERVER_NAME
|
||||||
|
)),
|
||||||
|
('When maintained the server with REINDEX on schema',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
data={
|
||||||
|
'database': 'postgres',
|
||||||
|
'schema': 'test_schema',
|
||||||
|
'op': 'REINDEX',
|
||||||
|
'verbose': False
|
||||||
|
},
|
||||||
|
cmd="REINDEX (VERBOSE);\n"
|
||||||
|
),
|
||||||
|
expected_msg="REINDEX SCHEMA on schema 'postgres/test_schema' "
|
||||||
|
"of server " + SERVER_NAME
|
||||||
|
)),
|
||||||
|
('When maintained the server with REINDEX on table',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
data={
|
||||||
|
'database': 'postgres',
|
||||||
|
'schema': 'test_schema',
|
||||||
|
'table': 'test_table',
|
||||||
|
'op': 'REINDEX',
|
||||||
'verbose': False
|
'verbose': False
|
||||||
},
|
},
|
||||||
cmd="REINDEX;\n"
|
cmd="REINDEX;\n"
|
||||||
),
|
),
|
||||||
expected_msg="REINDEX on database "
|
expected_msg="REINDEX TABLE on table "
|
||||||
"'postgres' of server " + SERVER_NAME,
|
"'postgres/test_schema/test_table' of server " +
|
||||||
expected_details_cmd='REINDEX;'
|
SERVER_NAME
|
||||||
|
)),
|
||||||
|
('When maintained the server with REINDEX on index',
|
||||||
|
dict(
|
||||||
|
class_params=dict(
|
||||||
|
sid=1,
|
||||||
|
data={
|
||||||
|
'database': 'postgres',
|
||||||
|
'schema': 'test_schema',
|
||||||
|
'table': 'test_table',
|
||||||
|
'primary_key': 'test_pkey',
|
||||||
|
'op': 'REINDEX',
|
||||||
|
'verbose': False
|
||||||
|
},
|
||||||
|
cmd="REINDEX;\n"
|
||||||
|
),
|
||||||
|
expected_msg="REINDEX INDEX on constraint "
|
||||||
|
"'postgres/test_schema/test_table/test_pkey' "
|
||||||
|
"of server " + SERVER_NAME
|
||||||
)),
|
)),
|
||||||
('When maintained the server with CLUSTER',
|
('When maintained the server with CLUSTER',
|
||||||
dict(
|
dict(
|
||||||
@ -100,16 +223,12 @@ class MaintenanceMessageTest(BaseTestGenerator):
|
|||||||
data={
|
data={
|
||||||
'database': 'postgres',
|
'database': 'postgres',
|
||||||
'op': 'CLUSTER',
|
'op': 'CLUSTER',
|
||||||
'vacuum_analyze': False,
|
|
||||||
'vacuum_freeze': False,
|
|
||||||
'vacuum_full': False,
|
|
||||||
'verbose': True
|
'verbose': True
|
||||||
},
|
},
|
||||||
cmd="CLUSTER VERBOSE;\n"
|
cmd="CLUSTER VERBOSE;\n"
|
||||||
),
|
),
|
||||||
expected_msg="CLUSTER on database "
|
expected_msg="CLUSTER on database 'postgres' of server " +
|
||||||
"'postgres' of server " + SERVER_NAME,
|
SERVER_NAME
|
||||||
expected_details_cmd='CLUSTER VERBOSE;'
|
|
||||||
|
|
||||||
)),
|
)),
|
||||||
]
|
]
|
||||||
@ -125,7 +244,3 @@ class MaintenanceMessageTest(BaseTestGenerator):
|
|||||||
|
|
||||||
# Check the expected message returned
|
# Check the expected message returned
|
||||||
self.assertEqual(maintenance_obj.message, self.expected_msg)
|
self.assertEqual(maintenance_obj.message, self.expected_msg)
|
||||||
|
|
||||||
# Check the command
|
|
||||||
obj_details = maintenance_obj.details(self.class_params['cmd'], None)
|
|
||||||
self.assertIn(self.expected_details_cmd, obj_details['query'])
|
|
||||||
|
@ -71,9 +71,6 @@ SUPPORTED_AUTH_SOURCES = [INTERNAL,
|
|||||||
|
|
||||||
BINARY_PATHS = {
|
BINARY_PATHS = {
|
||||||
"as_bin_paths": [
|
"as_bin_paths": [
|
||||||
{"version": "100000", "next_major_version": "110000",
|
|
||||||
"serverType": gettext("EDB Advanced Server 10"), "binaryPath": None,
|
|
||||||
"isDefault": False},
|
|
||||||
{"version": "110000", "next_major_version": "120000",
|
{"version": "110000", "next_major_version": "120000",
|
||||||
"serverType": gettext("EDB Advanced Server 11"), "binaryPath": None,
|
"serverType": gettext("EDB Advanced Server 11"), "binaryPath": None,
|
||||||
"isDefault": False},
|
"isDefault": False},
|
||||||
@ -88,12 +85,12 @@ BINARY_PATHS = {
|
|||||||
"isDefault": False},
|
"isDefault": False},
|
||||||
{"version": "150000", "next_major_version": "160000",
|
{"version": "150000", "next_major_version": "160000",
|
||||||
"serverType": gettext("EDB Advanced Server 15"), "binaryPath": None,
|
"serverType": gettext("EDB Advanced Server 15"), "binaryPath": None,
|
||||||
|
"isDefault": False},
|
||||||
|
{"version": "160000", "next_major_version": "170000",
|
||||||
|
"serverType": gettext("EDB Advanced Server 16"), "binaryPath": None,
|
||||||
"isDefault": False}
|
"isDefault": False}
|
||||||
],
|
],
|
||||||
"pg_bin_paths": [
|
"pg_bin_paths": [
|
||||||
{"version": "100000", "next_major_version": "110000",
|
|
||||||
"serverType": gettext("PostgreSQL 10"), "binaryPath": None,
|
|
||||||
"isDefault": False},
|
|
||||||
{"version": "110000", "next_major_version": "120000",
|
{"version": "110000", "next_major_version": "120000",
|
||||||
"serverType": gettext("PostgreSQL 11"), "binaryPath": None,
|
"serverType": gettext("PostgreSQL 11"), "binaryPath": None,
|
||||||
"isDefault": False},
|
"isDefault": False},
|
||||||
@ -108,6 +105,9 @@ BINARY_PATHS = {
|
|||||||
"isDefault": False},
|
"isDefault": False},
|
||||||
{"version": "150000", "next_major_version": "160000",
|
{"version": "150000", "next_major_version": "160000",
|
||||||
"serverType": gettext("PostgreSQL 15"), "binaryPath": None,
|
"serverType": gettext("PostgreSQL 15"), "binaryPath": None,
|
||||||
|
"isDefault": False},
|
||||||
|
{"version": "160000", "next_major_version": "170000",
|
||||||
|
"serverType": gettext("PostgreSQL 16"), "binaryPath": None,
|
||||||
"isDefault": False}
|
"isDefault": False}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,8 @@ def get_version_mapping_directories():
|
|||||||
:param server_type:
|
:param server_type:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
return ({'name': "15_plus", 'number': 150000},
|
return ({'name': "16_plus", 'number': 160000},
|
||||||
|
{'name': "15_plus", 'number': 150000},
|
||||||
{'name': "14_plus", 'number': 140000},
|
{'name': "14_plus", 'number': 140000},
|
||||||
{'name': "13_plus", 'number': 130000},
|
{'name': "13_plus", 'number': 130000},
|
||||||
{'name': "12_plus", 'number': 120000},
|
{'name': "12_plus", 'number': 120000},
|
||||||
|
@ -281,8 +281,8 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
|
|||||||
default_binary_path = self.server['default_binary_paths']
|
default_binary_path = self.server['default_binary_paths']
|
||||||
if default_binary_path is not None:
|
if default_binary_path is not None:
|
||||||
def get_server_version_string():
|
def get_server_version_string():
|
||||||
server_version = {150000: '15', 140000: '14', 130000: '13',
|
server_version = {160000: '16', 150000: '15', 140000: '14',
|
||||||
120000: '12', 110000: '11', 100000: '10'}
|
130000: '13', 120000: '12', 110000: '11'}
|
||||||
for k, v in server_version.items():
|
for k, v in server_version.items():
|
||||||
if k <= self.server_information['server_version']:
|
if k <= self.server_information['server_version']:
|
||||||
return v
|
return v
|
||||||
|
Loading…
Reference in New Issue
Block a user