Skip to content

Commit 7ab0cac

Browse files
authored
DPE-4247 Change binlog retention period (#478)
* set binlog retention to 7 days * sync libs * config in for binlog * bump libs
1 parent e657758 commit 7ab0cac

File tree

4 files changed

+37
-15
lines changed

4 files changed

+37
-15
lines changed

config.yaml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ options:
2323
Amount of memory in Megabytes to limit MySQL and associated process to.
2424
If unset, this will be decided according to the default memory limit in the selected profile.
2525
Only comes into effect when the `production` profile is selected.
26-
# Config options for the legacy 'mysql' interface
26+
# Config options for the legacy 'mysql' interface
2727
mysql-interface-user:
2828
description: The database username for the legacy 'mysql' interface
2929
type: string
@@ -46,7 +46,11 @@ options:
4646
Ref. at https://docs.percona.com/percona-server/8.0/audit-log-plugin.html#audit_log_strategy
4747
type: string
4848
default: async
49-
# Experimental features
49+
binlog_retention_days:
50+
description: Number of days for binary logs retention
51+
type: int
52+
default: 7
53+
# Experimental features
5054
experimental-max-connections:
5155
type: int
5256
description: |

lib/charms/mysql/v0/mysql.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ def wait_until_mysql_connection(self) -> None:
134134
# Increment this major API version when introducing breaking changes
135135
LIBAPI = 0
136136

137-
LIBPATCH = 67
137+
LIBPATCH = 69
138138

139139
UNIT_TEARDOWN_LOCKNAME = "unit-teardown"
140140
UNIT_ADD_LOCKNAME = "unit-add"
@@ -890,6 +890,7 @@ def render_mysqld_configuration( # noqa: C901
890890
audit_log_strategy: str,
891891
memory_limit: Optional[int] = None,
892892
experimental_max_connections: Optional[int] = None,
893+
binlog_retention_days: int,
893894
snap_common: str = "",
894895
) -> tuple[str, dict]:
895896
"""Render mysqld ini configuration file."""
@@ -939,6 +940,7 @@ def render_mysqld_configuration( # noqa: C901
939940
# disable memory instruments if we have less than 2GiB of RAM
940941
performance_schema_instrument = "'memory/%=OFF'"
941942

943+
binlog_retention_seconds = binlog_retention_days * 24 * 60 * 60
942944
config = configparser.ConfigParser(interpolation=None)
943945

944946
# do not enable slow query logs, but specify a log file path in case
@@ -954,6 +956,7 @@ def render_mysqld_configuration( # noqa: C901
954956
"general_log": "ON",
955957
"general_log_file": f"{snap_common}/var/log/mysql/general.log",
956958
"slow_query_log_file": f"{snap_common}/var/log/mysql/slowquery.log",
959+
"binlog_expire_logs_seconds": f"{binlog_retention_seconds}",
957960
"loose-audit_log_policy": "LOGINS",
958961
"loose-audit_log_file": f"{snap_common}/var/log/mysql/audit.log",
959962
}
@@ -1044,7 +1047,6 @@ def install_plugins(self, plugins: list[str]) -> None:
10441047
try:
10451048
installed_plugins = self._get_installed_plugins()
10461049
# disable super_read_only to install plugins
1047-
self.set_dynamic_variable("super_read_only", "OFF")
10481050
for plugin in plugins:
10491051
if plugin in installed_plugins:
10501052
# skip if the plugin is already installed
@@ -1054,9 +1056,15 @@ def install_plugins(self, plugins: list[str]) -> None:
10541056
logger.warning(f"{plugin=} is not supported")
10551057
continue
10561058

1059+
command = supported_plugins[plugin]
1060+
if super_read_only:
1061+
command = (
1062+
f"SET GLOBAL super_read_only=OFF; {command}"
1063+
"SET GLOBAL super_read_only=ON;"
1064+
)
10571065
logger.info(f"Installing {plugin=}")
10581066
self._run_mysqlcli_script(
1059-
supported_plugins[plugin],
1067+
command,
10601068
user=self.server_config_user,
10611069
password=self.server_config_password,
10621070
)
@@ -1065,25 +1073,27 @@ def install_plugins(self, plugins: list[str]) -> None:
10651073
f"Failed to install {plugin=}", # type: ignore
10661074
)
10671075
raise MySQLPluginInstallError
1068-
finally:
1069-
# restore original super_read_only value
1070-
if super_read_only:
1071-
self.set_dynamic_variable("super_read_only", "ON")
10721076

10731077
def uninstall_plugins(self, plugins: list[str]) -> None:
10741078
"""Uninstall plugins."""
10751079
super_read_only = self.get_variable_value("super_read_only").lower() == "on"
10761080
try:
10771081
installed_plugins = self._get_installed_plugins()
10781082
# disable super_read_only to uninstall plugins
1079-
self.set_dynamic_variable("super_read_only", "OFF")
10801083
for plugin in plugins:
10811084
if plugin not in installed_plugins:
10821085
# skip if the plugin is not installed
10831086
continue
10841087
logger.debug(f"Uninstalling plugin {plugin}")
1088+
1089+
command = f"UNINSTALL PLUGIN {plugin};"
1090+
if super_read_only:
1091+
command = (
1092+
f"SET GLOBAL super_read_only=OFF; {command}"
1093+
"SET GLOBAL super_read_only=ON;"
1094+
)
10851095
self._run_mysqlcli_script(
1086-
f"UNINSTALL PLUGIN {plugin}",
1096+
command,
10871097
user=self.server_config_user,
10881098
password=self.server_config_password,
10891099
)
@@ -1092,10 +1102,6 @@ def uninstall_plugins(self, plugins: list[str]) -> None:
10921102
f"Failed to uninstall {plugin=}", # type: ignore
10931103
)
10941104
raise MySQLPluginInstallError
1095-
finally:
1096-
# restore original super_read_only value
1097-
if super_read_only:
1098-
self.set_dynamic_variable("super_read_only", "ON")
10991105

11001106
def _get_installed_plugins(self) -> set[str]:
11011107
"""Return a set of explicitly installed plugins."""

src/charm.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ def _on_config_changed(self, _: EventBase) -> None: # noqa: C901
509509
audit_log_strategy=self.config.plugin_audit_strategy,
510510
memory_limit=memory_limit_bytes,
511511
experimental_max_connections=self.config.experimental_max_connections,
512+
binlog_retention_days=self.config.binlog_retention_days,
512513
)
513514

514515
changed_config = compare_dictionaries(previous_config_dict, new_config_dict)
@@ -588,6 +589,7 @@ def _write_mysqld_configuration(self):
588589
audit_log_strategy=self.config.plugin_audit_strategy,
589590
memory_limit=memory_limit_bytes,
590591
experimental_max_connections=self.config.experimental_max_connections,
592+
binlog_retention_days=self.config.binlog_retention_days,
591593
)
592594
self._mysql.write_content_to_file(path=MYSQLD_CONFIG_FILE, content=new_config_content)
593595

src/config.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class CharmConfig(BaseConfigModel):
5959
mysql_root_interface_user: Optional[str]
6060
mysql_root_interface_database: Optional[str]
6161
experimental_max_connections: Optional[int]
62+
binlog_retention_days: int
6263
plugin_audit_enabled: bool
6364
plugin_audit_strategy: str
6465

@@ -136,6 +137,15 @@ def experimental_max_connections_validator(cls, value: int) -> Optional[int]:
136137

137138
return value
138139

140+
@validator("binlog_retention_days")
141+
@classmethod
142+
def binlog_retention_days_validator(cls, value: int) -> int:
143+
"""Check binlog retention days."""
144+
if value < 1:
145+
raise ValueError("binlog-retention-days must be greater than 0")
146+
147+
return value
148+
139149
@validator("plugin_audit_strategy")
140150
@classmethod
141151
def plugin_audit_strategy_validator(cls, value: str) -> Optional[str]:

0 commit comments

Comments
 (0)