Skip to content

Commit f83ee03

Browse files
nasc17CustardTart32
authored andcommitted
[RDBMS] az postgres flexible-server index-tuning: Support tuning options operations (Azure#30851)
* Add commands for tuning options * New commands and upates for index-tuning group * Lint fix * Testing * Updates from PR * check casing
1 parent d6fc3c3 commit f83ee03

File tree

9 files changed

+2985
-4
lines changed

9 files changed

+2985
-4
lines changed

src/azure-cli/azure/cli/command_modules/rdbms/_client_factory.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,10 @@ def cf_postgres_flexible_private_link_resources(cli_ctx, _):
414414
return get_postgresql_flexible_management_client(cli_ctx).private_link_resources
415415

416416

417+
def cf_postgres_flexible_tuning_options(cli_ctx, _):
418+
return get_postgresql_flexible_management_client(cli_ctx).tuning_options
419+
420+
417421
def resource_client_factory(cli_ctx, subscription_id=None):
418422
return get_mgmt_service_client(cli_ctx, ResourceType.MGMT_RESOURCE_RESOURCES, subscription_id=subscription_id)
419423

src/azure-cli/azure/cli/command_modules/rdbms/_flexible_server_location_capabilities_util.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def _postgres_parse_list_capability(result):
5151
restricted = offer_restricted[0].status if offer_restricted else None
5252
zone_redundant = [feature for feature in supported_features if feature.name == "ZoneRedundantHa"]
5353
geo_backup = [feature for feature in supported_features if feature.name == "GeoBackup"]
54+
index_tuning = [feature for feature in supported_features if feature.name == "IndexTuning"]
5455

5556
if restricted == "Enabled":
5657
raise InvalidArgumentValueError("The location is restricted for provisioning of flexible servers. Please try using another region.")
@@ -60,6 +61,7 @@ def _postgres_parse_list_capability(result):
6061

6162
single_az = zone_redundant[0].status != "Enabled" if zone_redundant else True
6263
geo_backup_supported = geo_backup[0].status == "Enabled" if geo_backup else False
64+
index_tuning_supported = index_tuning[0].status == "Enabled" if index_tuning else False
6365

6466
tiers = result[0].supported_server_editions
6567
tiers_dict = {}
@@ -102,7 +104,8 @@ def _postgres_parse_list_capability(result):
102104
'single_az': single_az,
103105
'geo_backup_supported': geo_backup_supported,
104106
'zones': zones,
105-
'server_versions': versions
107+
'server_versions': versions,
108+
'index_tuning_supported': index_tuning_supported
106109
}
107110

108111

src/azure-cli/azure/cli/command_modules/rdbms/_helptext_pg.py

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@
681681
type: command
682682
short-summary: Get the parameter for a flexible server."
683683
examples:
684-
- name: Get the parameter for a server.W
684+
- name: Get the parameter for a server.
685685
text: az postgres flexible-server parameter show --resource-group testGroup --server-name servername --name parameterName
686686
"""
687687

@@ -1170,3 +1170,56 @@
11701170
- name: Update allowed mirrored databases.
11711171
text: az postgres flexible-server fabric-mirroring update-databases -g testgroup -s testsvr --database-names testdb2 testdb3
11721172
"""
1173+
1174+
helps['postgres flexible-server index-tuning'] = """
1175+
type: group
1176+
short-summary: Index tuning analyzes read queries captured in Query Store and recommends index changes to optimize these queries.
1177+
"""
1178+
1179+
helps['postgres flexible-server index-tuning update'] = """
1180+
type: command
1181+
short-summary: Update index tuning to be enabled/disabled for a PostgreSQL flexible server.
1182+
examples:
1183+
- name: Update index tuning to be enabled/disabled for a PostgreSQL flexible server.
1184+
text: az postgres flexible-server index-tuning update -g testgroup -s testsvr --enabled True
1185+
"""
1186+
1187+
helps['postgres flexible-server index-tuning show'] = """
1188+
type: command
1189+
short-summary: Show state of index tuning for a PostgreSQL flexible server.
1190+
examples:
1191+
- name: Show state of index tuning for a PostgreSQL flexible server.
1192+
text: az postgres flexible-server index-tuning show -g testgroup -s testsvr
1193+
"""
1194+
1195+
helps['postgres flexible-server index-tuning list-settings'] = """
1196+
type: command
1197+
short-summary: Get tuning settings associated for a PostgreSQL flexible server.
1198+
examples:
1199+
- name: Get tuning settings for a PostgreSQL flexible server.
1200+
text: az postgres flexible-server index-tuning list-settings -g testgroup -s testsvr
1201+
"""
1202+
1203+
helps['postgres flexible-server index-tuning show-settings'] = """
1204+
type: command
1205+
short-summary: Get a tuning setting for a PostgreSQL flexible server.
1206+
examples:
1207+
- name: Get a tuning setting for a PostgreSQL flexible server.
1208+
text: az postgres flexible-server index-tuning show-settings -g testgroup -s testsvr --name setting-name
1209+
"""
1210+
1211+
helps['postgres flexible-server index-tuning set-settings'] = """
1212+
type: command
1213+
short-summary: Update a tuning setting for a PostgreSQL flexible server.
1214+
examples:
1215+
- name: Update a tuning setting for a PostgreSQL flexible server.
1216+
text: az postgres flexible-server index-tuning set-settings -g testgroup -s testsvr --name setting-name --value setting-value
1217+
"""
1218+
1219+
helps['postgres flexible-server index-tuning list-recommendations'] = """
1220+
type: command
1221+
short-summary: Get available tuning index recommendations associated with a PostgreSQL flexible server.
1222+
examples:
1223+
- name: Get tuning index recommendations for a PostgreSQL flexible server. Filter by selected type.
1224+
text: az postgres flexible-server index-tuning list-recommendations -g testgroup -s testsvr --recommendation-type CreateIndex
1225+
"""

src/azure-cli/azure/cli/command_modules/rdbms/_params.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from .randomname.generate import generate_username
2424
from ._flexible_server_util import get_current_time
2525
from argcomplete.completers import FilesCompleter
26+
from ._util import get_index_tuning_settings_map
2627

2728

2829
def load_arguments(self, _): # pylint: disable=too-many-statements, too-many-locals
@@ -1034,6 +1035,37 @@ def _flexible_server_params(command_group):
10341035
c.argument('resource_group_name', arg_type=resource_group_name_type)
10351036
c.argument('server_name', options_list=['--server-name', '-s'], id_part='name', arg_type=server_name_arg_type, required=False)
10361037

1038+
# index tuning
1039+
if command_group == 'postgres':
1040+
for scope in ['update', 'show', 'list-settings', 'show-settings', 'set-settings', 'list-recommendations']:
1041+
argument_context_string = '{} flexible-server index-tuning {}'.format(command_group, scope)
1042+
with self.argument_context(argument_context_string) as c:
1043+
c.argument('server_name', options_list=['--server-name', '-s'], arg_type=server_name_arg_type)
1044+
1045+
with self.argument_context('{} flexible-server index-tuning update'.format(command_group)) as c:
1046+
c.argument('index_tuning_enabled',
1047+
options_list=['--enabled'],
1048+
required=True,
1049+
help='Enable or disable index tuning feature.',
1050+
arg_type=get_enum_type(['True', 'False']))
1051+
1052+
with self.argument_context('{} flexible-server index-tuning list-recommendations'.format(command_group)) as c:
1053+
c.argument('recommendation_type',
1054+
options_list=['--recommendation-type', '-r'],
1055+
help='Retrieve recommendations based on type.',
1056+
arg_type=get_enum_type(['CreateIndex', 'DropIndex']))
1057+
1058+
for scope in ['show-settings', 'set-settings']:
1059+
argument_context_string = '{} flexible-server index-tuning {}'.format(command_group, scope)
1060+
with self.argument_context(argument_context_string) as c:
1061+
c.argument('setting_name', options_list=['--name', '-n'], required=True,
1062+
arg_type=get_enum_type(get_index_tuning_settings_map().keys()),
1063+
help='The name of the tuning setting.')
1064+
1065+
with self.argument_context('{} flexible-server index-tuning set-settings'.format(command_group)) as c:
1066+
c.argument('value', options_list=['--value', '-v'],
1067+
help='Value of the tuning setting.')
1068+
10371069
# GTID
10381070
if command_group == 'mysql':
10391071
with self.argument_context('{} flexible-server gtid reset'.format(command_group)) as c:

src/azure-cli/azure/cli/command_modules/rdbms/_util.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,20 @@ def call(*args, **kwargs):
103103
sleep(interval_sec)
104104
return call
105105
return decorate
106+
107+
108+
def get_index_tuning_settings_map():
109+
return {
110+
'analysis_interval': 'index_tuning.analysis_interval',
111+
'max_columns_per_index': 'index_tuning.max_columns_per_index',
112+
'max_index_count': 'index_tuning.max_index_count',
113+
'max_indexes_per_table': 'index_tuning.max_indexes_per_table',
114+
'max_queries_per_database': 'index_tuning.max_queries_per_database',
115+
'max_regression_factor': 'index_tuning.max_regression_factor',
116+
'max_total_size_factor': 'index_tuning.max_total_size_factor',
117+
'min_improvement_factor': 'index_tuning.min_improvement_factor',
118+
'mode': 'index_tuning.mode',
119+
'unused_dml_per_table': 'index_tuning.unused_dml_per_table',
120+
'unused_min_period': 'index_tuning.unused_min_period',
121+
'unused_reads_per_table': 'index_tuning.unused_reads_per_table'
122+
}

src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_commands.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,3 +296,12 @@ def load_flexibleserver_command_table(self, _):
296296
g.custom_command('start', 'flexible_server_fabric_mirroring_start')
297297
g.custom_command('stop', 'flexible_server_fabric_mirroring_stop')
298298
g.custom_command('update-databases', 'flexible_server_fabric_mirroring_update_databases')
299+
300+
with self.command_group('postgres flexible-server index-tuning', postgres_flexible_config_sdk,
301+
client_factory=cf_postgres_flexible_config) as g:
302+
g.custom_command('update', 'index_tuning_update', custom_command_type=flexible_servers_custom_postgres)
303+
g.custom_show_command('show', 'index_tuning_show', custom_command_type=flexible_servers_custom_postgres)
304+
g.custom_command('list-settings', 'index_tuning_settings_list', custom_command_type=flexible_servers_custom_postgres)
305+
g.custom_command('show-settings', 'index_tuning_settings_get', custom_command_type=flexible_servers_custom_postgres)
306+
g.custom_command('set-settings', 'index_tuning_settings_set', custom_command_type=flexible_servers_custom_postgres)
307+
g.custom_command('list-recommendations', 'recommendations_list', custom_command_type=flexible_servers_custom_postgres)

src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@
2727
cf_postgres_flexible_db, cf_postgres_check_resource_availability, cf_postgres_flexible_servers, \
2828
cf_postgres_check_resource_availability_with_location, \
2929
cf_postgres_flexible_private_dns_zone_suffix_operations, \
30-
cf_postgres_flexible_private_endpoint_connections
30+
cf_postgres_flexible_private_endpoint_connections, \
31+
cf_postgres_flexible_tuning_options
3132
from ._flexible_server_util import generate_missing_parameters, resolve_poller, \
3233
generate_password, parse_maintenance_window, get_current_time, build_identity_and_data_encryption, \
3334
_is_resource_name, get_tenant_id, get_case_insensitive_key_value, get_enum_value_true_false
3435
from ._flexible_server_location_capabilities_util import get_postgres_location_capability_info
36+
from ._util import get_index_tuning_settings_map
3537
from .flexible_server_custom_common import create_firewall_rule
3638
from .flexible_server_virtual_network import prepare_private_network, prepare_private_dns_zone, prepare_public_network
3739
from .validators import pg_arguments_validator, validate_server_name, validate_and_format_restore_point_in_time, \
@@ -1606,6 +1608,91 @@ def _update_parameters(cmd, client, server_name, configuration_name, resource_gr
16061608
client.begin_update(resource_group_name, server_name, configuration_name, parameters), cmd.cli_ctx, 'PostgreSQL Parameter update')
16071609

16081610

1611+
def index_tuning_update(cmd, client, resource_group_name, server_name, index_tuning_enabled):
1612+
validate_resource_group(resource_group_name)
1613+
source = "user-override"
1614+
1615+
if index_tuning_enabled == "True":
1616+
subscription = get_subscription_id(cmd.cli_ctx)
1617+
postgres_source_client = get_postgresql_flexible_management_client(cmd.cli_ctx, subscription)
1618+
source_server_object = postgres_source_client.servers.get(resource_group_name, server_name)
1619+
location = ''.join(source_server_object.location.lower().split())
1620+
list_location_capability_info = get_postgres_location_capability_info(cmd, location)
1621+
index_tuning_supported = list_location_capability_info['index_tuning_supported']
1622+
if not index_tuning_supported:
1623+
raise CLIError("Index tuning is not supported for the server.")
1624+
1625+
logger.warning("Enabling index tuning for the server.")
1626+
configuration_name = "index_tuning.mode"
1627+
value = "report"
1628+
_update_parameters(cmd, client, server_name, configuration_name, resource_group_name, source, value)
1629+
configuration_name = "pg_qs.query_capture_mode"
1630+
query_capture_mode_configuration = client.get(resource_group_name, server_name, configuration_name)
1631+
1632+
if query_capture_mode_configuration.value.lower() == "none":
1633+
value = "all"
1634+
_update_parameters(cmd, client, server_name, configuration_name, resource_group_name, source, value)
1635+
logger.warning("Index tuning is enabled for the server.")
1636+
else:
1637+
logger.warning("Disabling index tuning for the server.")
1638+
configuration_name = "index_tuning.mode"
1639+
value = "off"
1640+
_update_parameters(cmd, client, server_name, configuration_name, resource_group_name, source, value)
1641+
logger.warning("Index tuning is disabled for the server.")
1642+
1643+
1644+
def index_tuning_show(client, resource_group_name, server_name):
1645+
validate_resource_group(resource_group_name)
1646+
index_tuning_configuration = client.get(resource_group_name, server_name, "index_tuning.mode")
1647+
query_capture_mode_configuration = client.get(resource_group_name, server_name, "pg_qs.query_capture_mode")
1648+
1649+
if index_tuning_configuration.value.lower() == "report" and query_capture_mode_configuration.value.lower() != "none":
1650+
logger.warning("Index tuning is enabled for the server.")
1651+
else:
1652+
logger.warning("Index tuning is disabled for the server.")
1653+
1654+
1655+
def index_tuning_settings_list(cmd, client, resource_group_name, server_name):
1656+
validate_resource_group(resource_group_name)
1657+
index_tuning_configurations_map_values = get_index_tuning_settings_map().values()
1658+
configurations_list = client.list_by_server(resource_group_name, server_name)
1659+
1660+
# Filter the list based on the values in the dictionary
1661+
index_tuning_settings = [setting for setting in configurations_list if setting.name in index_tuning_configurations_map_values]
1662+
1663+
return index_tuning_settings
1664+
1665+
1666+
def index_tuning_settings_get(cmd, client, resource_group_name, server_name, setting_name):
1667+
validate_resource_group(resource_group_name)
1668+
index_tuning_configurations_map = get_index_tuning_settings_map()
1669+
index_tuning_configuration_name = index_tuning_configurations_map[setting_name]
1670+
1671+
return client.get(
1672+
resource_group_name=resource_group_name,
1673+
server_name=server_name,
1674+
configuration_name=index_tuning_configuration_name)
1675+
1676+
1677+
def index_tuning_settings_set(client, resource_group_name, server_name, setting_name, value=None):
1678+
source = "user-override" if value else None
1679+
tuning_settings = get_index_tuning_settings_map()
1680+
configuration_name = tuning_settings[setting_name]
1681+
return flexible_parameter_update(client, server_name, configuration_name, resource_group_name, source, value)
1682+
1683+
1684+
def recommendations_list(cmd, resource_group_name, server_name, recommendation_type=None):
1685+
validate_resource_group(resource_group_name)
1686+
tuning_options_client = cf_postgres_flexible_tuning_options(cmd.cli_ctx, None)
1687+
1688+
return tuning_options_client.list_recommendations(
1689+
resource_group_name=resource_group_name,
1690+
server_name=server_name,
1691+
tuning_option="index",
1692+
recommendation_type=recommendation_type
1693+
)
1694+
1695+
16091696
def _update_private_endpoint_connection_status(cmd, client, resource_group_name, server_name,
16101697
private_endpoint_connection_name, is_approved=True, description=None): # pylint: disable=unused-argument
16111698
validate_resource_group(resource_group_name)

0 commit comments

Comments
 (0)