Skip to content

Commit

Permalink
DPE-4247 Change binlog retention period (#478)
Browse files Browse the repository at this point in the history
* set binlog retention to 7 days

* sync libs

* config in for binlog

* bump libs
  • Loading branch information
paulomach authored Aug 14, 2024
1 parent e657758 commit 7ab0cac
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 15 deletions.
8 changes: 6 additions & 2 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ options:
Amount of memory in Megabytes to limit MySQL and associated process to.
If unset, this will be decided according to the default memory limit in the selected profile.
Only comes into effect when the `production` profile is selected.
# Config options for the legacy 'mysql' interface
# Config options for the legacy 'mysql' interface
mysql-interface-user:
description: The database username for the legacy 'mysql' interface
type: string
Expand All @@ -46,7 +46,11 @@ options:
Ref. at https://docs.percona.com/percona-server/8.0/audit-log-plugin.html#audit_log_strategy
type: string
default: async
# Experimental features
binlog_retention_days:
description: Number of days for binary logs retention
type: int
default: 7
# Experimental features
experimental-max-connections:
type: int
description: |
Expand Down
32 changes: 19 additions & 13 deletions lib/charms/mysql/v0/mysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def wait_until_mysql_connection(self) -> None:
# Increment this major API version when introducing breaking changes
LIBAPI = 0

LIBPATCH = 67
LIBPATCH = 69

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

binlog_retention_seconds = binlog_retention_days * 24 * 60 * 60
config = configparser.ConfigParser(interpolation=None)

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

command = supported_plugins[plugin]
if super_read_only:
command = (
f"SET GLOBAL super_read_only=OFF; {command}"
"SET GLOBAL super_read_only=ON;"
)
logger.info(f"Installing {plugin=}")
self._run_mysqlcli_script(
supported_plugins[plugin],
command,
user=self.server_config_user,
password=self.server_config_password,
)
Expand All @@ -1065,25 +1073,27 @@ def install_plugins(self, plugins: list[str]) -> None:
f"Failed to install {plugin=}", # type: ignore
)
raise MySQLPluginInstallError
finally:
# restore original super_read_only value
if super_read_only:
self.set_dynamic_variable("super_read_only", "ON")

def uninstall_plugins(self, plugins: list[str]) -> None:
"""Uninstall plugins."""
super_read_only = self.get_variable_value("super_read_only").lower() == "on"
try:
installed_plugins = self._get_installed_plugins()
# disable super_read_only to uninstall plugins
self.set_dynamic_variable("super_read_only", "OFF")
for plugin in plugins:
if plugin not in installed_plugins:
# skip if the plugin is not installed
continue
logger.debug(f"Uninstalling plugin {plugin}")

command = f"UNINSTALL PLUGIN {plugin};"
if super_read_only:
command = (
f"SET GLOBAL super_read_only=OFF; {command}"
"SET GLOBAL super_read_only=ON;"
)
self._run_mysqlcli_script(
f"UNINSTALL PLUGIN {plugin}",
command,
user=self.server_config_user,
password=self.server_config_password,
)
Expand All @@ -1092,10 +1102,6 @@ def uninstall_plugins(self, plugins: list[str]) -> None:
f"Failed to uninstall {plugin=}", # type: ignore
)
raise MySQLPluginInstallError
finally:
# restore original super_read_only value
if super_read_only:
self.set_dynamic_variable("super_read_only", "ON")

def _get_installed_plugins(self) -> set[str]:
"""Return a set of explicitly installed plugins."""
Expand Down
2 changes: 2 additions & 0 deletions src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,7 @@ def _on_config_changed(self, _: EventBase) -> None: # noqa: C901
audit_log_strategy=self.config.plugin_audit_strategy,
memory_limit=memory_limit_bytes,
experimental_max_connections=self.config.experimental_max_connections,
binlog_retention_days=self.config.binlog_retention_days,
)

changed_config = compare_dictionaries(previous_config_dict, new_config_dict)
Expand Down Expand Up @@ -588,6 +589,7 @@ def _write_mysqld_configuration(self):
audit_log_strategy=self.config.plugin_audit_strategy,
memory_limit=memory_limit_bytes,
experimental_max_connections=self.config.experimental_max_connections,
binlog_retention_days=self.config.binlog_retention_days,
)
self._mysql.write_content_to_file(path=MYSQLD_CONFIG_FILE, content=new_config_content)

Expand Down
10 changes: 10 additions & 0 deletions src/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class CharmConfig(BaseConfigModel):
mysql_root_interface_user: Optional[str]
mysql_root_interface_database: Optional[str]
experimental_max_connections: Optional[int]
binlog_retention_days: int
plugin_audit_enabled: bool
plugin_audit_strategy: str

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

return value

@validator("binlog_retention_days")
@classmethod
def binlog_retention_days_validator(cls, value: int) -> int:
"""Check binlog retention days."""
if value < 1:
raise ValueError("binlog-retention-days must be greater than 0")

return value

@validator("plugin_audit_strategy")
@classmethod
def plugin_audit_strategy_validator(cls, value: str) -> Optional[str]:
Expand Down

0 comments on commit 7ab0cac

Please sign in to comment.