diff --git a/.agent/rules/04_best_practices.md b/.agent/rules/04_best_practices.md index de429d3eb..abe4e76c4 100644 --- a/.agent/rules/04_best_practices.md +++ b/.agent/rules/04_best_practices.md @@ -99,6 +99,7 @@ Beyond hard constraints, following established patterns ensures code durability, - Release notes MUST be verified during the `/release-manager` orchestration to prevent omission on the remote repository. - Ensure `releases/v[VERSION].md` exists and is synchronized with the current release. +- **STRICT PROHIBITION**: Never modify or update the release notes of previous versions (`releases/v[OLD_VERSION].md`). Only update or edit the release notes corresponding to the current release version. ## ✅ Verification diff --git a/.agent/workflows/compliance-sentinel.md b/.agent/workflows/compliance-sentinel.md index cedfc3d8d..0ee961144 100644 --- a/.agent/workflows/compliance-sentinel.md +++ b/.agent/workflows/compliance-sentinel.md @@ -60,13 +60,32 @@ Verify that laboratory logs are free of regressions and anomalies, and that any perl build/audit_logs.pl --dir=examples --verbose # 2. Verify POTENTIAL_ISSUES exists if anomalies found -if [ -s POTENTIAL_ISSUES ]; then - echo "Audit check: POTENTIAL_ISSUES is documented." +if [ -s POTENTIAL_ISSUES.md ]; then + echo "Audit check: POTENTIAL_ISSUES.md is documented." else - echo "WARNING: POTENTIAL_ISSUES is empty, ensure all audit findings are handled." + echo "WARNING: POTENTIAL_ISSUES.md is empty, ensure all audit findings are handled." fi ``` -## 6. Execution +## 6. Core Check: Historical Release Notes Immutability + +Ensure no historical release notes files have been modified. + +```bash +current_version=$(cat CURRENT_VERSION.txt | tr -d '\n') +base_ref="origin/master" +if ! git rev-parse --verify $base_ref >/dev/null 2>&1; then + base_ref="master" +fi +for file in $(git diff --name-only $base_ref...HEAD -- releases/); do + if [ -f "$file" ] && [ "$file" != "releases/v$current_version.md" ]; then + echo "FAIL: Historical release notes modified: $file. Only releases/v$current_version.md can be updated." + exit 1 + fi +done +``` + +## 7. Execution Run these checks before any major commit or release. + diff --git a/.agent/workflows/run-tests.md b/.agent/workflows/run-tests.md index 572f63e6d..1d88f65e4 100644 --- a/.agent/workflows/run-tests.md +++ b/.agent/workflows/run-tests.md @@ -21,8 +21,8 @@ Execute the standard Perl test suite to verify core logic. // turbo ```bash -# Using prove -prove -r tests/ +# Using the test auditor script +perl build/audit_tests.pl # OR via Makefile make unit-tests diff --git a/COMMIT_AND_RELEASE.md b/COMMIT_AND_RELEASE.md index efe1eb381..8f7981f6b 100644 --- a/COMMIT_AND_RELEASE.md +++ b/COMMIT_AND_RELEASE.md @@ -52,7 +52,7 @@ Validate your changes locally using both unit tests and multi-database lab testi ```bash make unit-tests # or - prove -r tests/ + prove -r tests/ # (or perl build/audit_tests.pl) ``` 2. **Laboratory Tests (Docker)**: Ensure code executes correctly across multiple database versions (MySQL, MariaDB, Percona Server): diff --git a/CURRENT_VERSION.txt b/CURRENT_VERSION.txt index 6c7b14fe2..28e77f04c 100644 --- a/CURRENT_VERSION.txt +++ b/CURRENT_VERSION.txt @@ -1 +1 @@ -2.8.42 +2.8.43 diff --git a/Changelog b/Changelog index 6224d6e99..177641328 100644 --- a/Changelog +++ b/Changelog @@ -1,40 +1,51 @@ # MySQLTuner Changelog -2.8.42 2026-05-25 - -- chore: bump version to 2.8.42. +2.8.43 2026-05-25 + +- chore: bump version to 2.8.43. +- feat: add --compress-dump option to compress SQL schema dumps using gzip. +- feat: add --dump-limit option to limit row extraction count for CSV dumps. +- feat: export naming convention deviations and missing foreign keys to CSV files. +- feat: write schema export manifest files to track dumped files. +- feat: add unified health score breakdown to CLI output and HTML laboratory reports. +- feat: implement test output auditor script to scan test results for Perl execution errors and runtime warnings. - fix: resolve invalid login credentials error by defaulting to root when only --pass is set and escaping single quotes in passwords (#781). - fix: resolve fake aborted connections count increase during password strength checks (#900). - fix: resolve EOF metadata corruption and duplicated configurations in Emacs block (#904). - fix: prevent plaintext password leakage in weak password diagnostic messages. - fix: implement symlink verification and atomic writes for aborted connects state file protection. - fix: append transport-specific host and container identifiers in state file path to prevent collisions. +- fix: correct authentication plugin checks mock implementation in unit tests to prevent health score deduction bypass. - test: strengthen authentication plugin checks and add verification suite for state file protections. +- test: add comprehensive test suite for weighted health score and score breakdowns. - ci: optimize release notes generation to isolate branch changes. -- perf: optimize --dumpdir performance by excluding heavy RDS/Aurora and internal metrics. +- docs: complete documentation refresh synchronizing README.md, INTERNALS.md, USAGE.md, and all translated READMEs with v2.8.43 script capabilities. - docs: improve authentication plugins algorithm labels and resolve absolute documentation links. +- perf: optimize --dumpdir performance by excluding heavy RDS/Aurora and internal metrics. - refactor: catch explicit exception classes in build/release_gen.py to prevent masking system signals. +- refactor: replace generic file preview logic with explicit descriptive labeling for database audit artifacts. +- refactor: html report to get better information about each version. + +2.8.42 2026-05-17 + +- chore: automated project metadata update (empty release). 2.8.41 2026-05-17 +- feat: enhance --forcemem and --forceswap to support human-readable memory units (B, K, M, G, T, P). +- feat: implement idiomatic Perl Boolean practices across the project (#34). +- feat: add recommendation for `table_open_cache_instances` based on CPU cores (#480). +- feat: improve syslog and systemd journal detection for error logs (#440). +- feat: initialize `$mysqllogin` to avoid uninitialized value warnings (#490). - fix: filter MySQL CLI password warning from execute_system_command output. - fix: prevent division by zero crash in percentage() with non-numeric values. - fix: resolve SQL execution failure (return code 256) in MySQL 9.x containers by updating batch execution flags. -- ci: refine audit_logs.pl to prevent false positive warnings on successful [OK] output. -- feat: enhance --forcemem and --forceswap to support human-readable memory units (B, K, M, G, T, P). -- ci: enhance Quality Gate to strictly enforce zero-warning policy on GitHub Actions tests. -- ci: implement dynamic CI test environment detection by wrapping configuration extraction. -- ci: refactor GitHub Actions release and prerelease workflows to support dynamic versions and checksum generation. - fix: Restore compatibility with older Perl versions (by @jasongill). -- feat: implement idiomatic Perl Boolean practices across the project (#34). -- refactor: update CLI metadata to use `undef` as default for string/path options. -- refactor: replace non-idiomatic `eq '0'`, `ne 0`, etc., with standard truthiness checks. - fix: wrap template loading in `get_template_model()` to avoid `uninitialized value` warnings during `require`. - fix: allow `--updateversion` to work on hosts without `mysql`/`mariadb` installed (#36). - fix: skip local SSL certificate warnings if they are in an inaccessible `datadir` (#33). - fix: correct false positives in `check_removed_innodb_variables` by distinguishing real server variables from internal ones (#32). -- refactor: replace "master"/"slave" terminology with "source"/"replica" for cultural sensitivity (#888). - fix: improve join_buffer_size recommendation formatting in Variables to Adjust (#881). - fix: suppress MySQL client warning regarding 'DISABLED' boolean value for SSL (#887). - fix: correctly handle `--defaults-file` and `--defaults-extra-file` without dropping options (#605). @@ -44,15 +55,19 @@ - fix: prevent `AUTO_INCREMENT` capacity false positives for empty tables (#37). - fix: refactor InnoDB Redo Log Capacity logic to be workload-based and avoid false positives (#714, #737, #777). - fix: add guards against division by zero in calculations for improved stability (#435). -- feat: add recommendation for `table_open_cache_instances` based on CPU cores (#480). -- feat: improve syslog and systemd journal detection for error logs (#440). -- feat: initialize `$mysqllogin` to avoid uninitialized value warnings (#490). - fix: add truthiness guards to `mysql_innodb` and `mysql_stats` subroutines. - fix: improve `which` logic for better container/minimal environment support. - fix: enhance login failure reporting with detailed output. - fix: handle Plesk Obsidian 18.0.76.5+ removing --show-password (#42). -- chore: automated project maintenance and cleanup (extracted `RULES.md`, `MEMORY_DB.md`, `TESTS.md`). +- ci: refine audit_logs.pl to prevent false positive warnings on successful [OK] output. +- ci: enhance Quality Gate to strictly enforce zero-warning policy on GitHub Actions tests. +- ci: implement dynamic CI test environment detection by wrapping configuration extraction. +- ci: refactor GitHub Actions release and prerelease workflows to support dynamic versions and checksum generation. - ci: migrate maintenance script to GitHub Actions. +- refactor: update CLI metadata to use `undef` as default for string/path options. +- refactor: replace non-idiomatic `eq '0'`, `ne 0`, etc., with standard truthiness checks. +- refactor: replace "master"/"slave" terminology with "source"/"replica" for cultural sensitivity (#888). +- chore: automated project maintenance and cleanup (extracted `RULES.md`, `MEMORY_DB.md`, `TESTS.md`). - chore(deps): update docker/setup-buildx-action action to v4. - chore(deps): update docker/build-push-action action to v7. - chore(deps): update docker/login-action action to v4. diff --git a/FEATURES.md b/FEATURES.md index 9aed2ad5e..701bd2b3a 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -58,3 +58,4 @@ Features list for option: --feature (dev only) * system_recommendations * validate_mysql_version * validate_tuner_version +* write_manifest_files diff --git a/INTERNALS.md b/INTERNALS.md index d42f797f3..93aa3a696 100644 --- a/INTERNALS.md +++ b/INTERNALS.md @@ -13,6 +13,8 @@ - [Mysql error log file analysis](#mysql-error-log-file-analysis) - [MySQL Storage engine general information](#mysql-storage-engine-general-information) - [MySQLTuner security checks](#mysqltuner-security-checks) +- [MySQLTuner SSL/TLS security checks](#mysqltuner-ssltls-security-checks) +- [MySQLTuner authentication plugin auditing](#mysqltuner-authentication-plugin-auditing) - [MySQLTuner CVE vulnerabilities detection](#mysqltuner-cve-vulnerabilities-detection) - [MySQLTuner database information](#mysqltuner-database-information) - [MySQLTuner index information](#mysqltuner-index-information) @@ -35,8 +37,23 @@ - [MySQLTuner RocksDb information](#mysqltuner-rocksdb-information) - [MySQLTuner Thread pool information](#mysqltuner-thread-pool-information) - [MySQLTuner performance schema and sysschema information](#mysqltuner-performance-schema-and-sysschema-information) +- [MySQLTuner Table Structure Analysis](#mysqltuner-table-structure-analysis) +- [MySQLTuner Naming Conventions Analysis](#mysqltuner-naming-conventions-analysis) +- [MySQLTuner Foreign Key Analysis](#mysqltuner-foreign-key-analysis) +- [MySQLTuner MySQL 8.0+ / MariaDB Modeling Checks](#mysqltuner-mysql-80--mariadb-modeling-checks) +- [MySQLTuner Data Type Optimization](#mysqltuner-data-type-optimization) +- [MySQLTuner Schema Sanitization](#mysqltuner-schema-sanitization) - [MySQLTuner Cloud and SSH integration](#mysqltuner-cloud-and-ssh-integration) +- [MySQLTuner Cloud Autodiscovery](#mysqltuner-cloud-autodiscovery) +- [MySQLTuner Infrastructure Awareness](#mysqltuner-infrastructure-awareness) - [MySQLTuner Container and Systemd log integration](#mysqltuner-container-and-systemd-log-integration) +- [MySQLTuner Weighted Health Score](#mysqltuner-weighted-health-score) +- [MySQLTuner Predictive Capacity Analysis](#mysqltuner-predictive-capacity-analysis) +- [MySQLTuner Guided Auto-Fix Engine](#mysqltuner-guided-auto-fix-engine) +- [MySQLTuner Query Anti-Pattern Detection](#mysqltuner-query-anti-pattern-detection) +- [MySQLTuner Sysbench Integration](#mysqltuner-sysbench-integration) +- [MySQLTuner Historical Trend Analysis](#mysqltuner-historical-trend-analysis) +- [MySQLTuner Aborted Connections Management](#mysqltuner-aborted-connections-management) ## MySQLTuner steps @@ -54,11 +71,14 @@ - Show parameters impacting performance during analysis - Show information about databases (option: --dbstat) - Show information about tables (option: --tbstat) +- Show information about columns (option: --colstat) - Show information about indexes (option: --idxstat) - Show information about views, triggers, and routines - Show information about plugins (option: --plugininfo) - Show enabled storage engines -- Display some security recommendations +- Display security recommendations +- Display SSL/TLS security audit +- Display authentication plugin audit - CVE vulnerabilities detection - Calculate everything we need - Print the server stats @@ -66,12 +86,21 @@ - Print InnoDB stats - Print AriaDB stats - Print Galera cluster stats -- Print replication info +- Print replication info (Source/Replica, GTID, Semi-sync) - Query Anti-Pattern Detection (Performance Schema digests) - Print Storage Engine specific stats (TokuDB, RocksDB, Spider, etc.) - Print Performance Schema stats -- Sysbench result analysis (if provided) -- Historical Trend Analysis (if comparison file provided) +- Table structure analysis (option: --structstat) +- Naming conventions analysis (option: --structstat) +- Foreign key analysis (option: --structstat) +- MySQL 8.0+ / MariaDB modeling checks (option: --structstat) +- Data type optimization analysis (option: --structstat) +- Schema sanitization checks (option: --structstat) +- Weighted Health Score KPI calculation and display +- Predictive Capacity Analysis (memory headroom, disk growth) +- Sysbench result analysis (if provided via --sysbench-file) +- Historical Trend Analysis (if comparison file provided via --compare-file) +- Guided Auto-Fix Snippets generation - Make recommendations based on stats - Close reportfile if needed - Dump result if debug is on @@ -114,10 +143,10 @@ ## MySQLTuner Server version checks -- EOL MySQL version check - -- Currently MySQL < 5.1 are considered EOL +- EOL MySQL and MariaDB version check +- Currently MySQL < 5.5 and MariaDB < 10.6 are considered EOL - Using 5.5+ version of MySQL for performance issue (asynchronous IO) +- MySQL 9.x readiness: detection of removed variables and eliminated authentication methods ## Mysql error log file analysis @@ -150,6 +179,36 @@ - Weak password check (possibly using cracklib later?) - Using basic_passwords.txt as password database - Password list checks can be avoided (option: --skippassword) +- Max password checks configurable (option: --max-password-checks, default: 100) + +## MySQLTuner SSL/TLS security checks + +- Current session encryption status (Ssl_cipher check) +- Global SSL support (have_ssl variable) +- `require_secure_transport` enforcement (MySQL 5.7+, MariaDB 10.5+) +- TLS version audit: + - Warn if TLSv1.0 or TLSv1.1 are enabled (insecure) + - Verify TLSv1.2 or TLSv1.3 are available +- SSL certificate presence and local audit: + - Certificate file existence and permissions + - Certificate expiration date check +- Remote user SSL enforcement: + - Check if remote users (`%` host) require SSL +- CSV export of SSL issues (with --dumpdir) + +## MySQLTuner authentication plugin auditing + +- Detection of insecure authentication plugins: + - `mysql_native_password` (SHA-1 based, deprecated in MySQL 8.0+) + - `mysql_old_password` (legacy, insecure) + - `sha256_password` (deprecated in favor of `caching_sha2_password`) +- MySQL 9.x readiness diagnostics: + - Eliminated authentication methods detection + - Migration path recommendations +- MariaDB-specific recommendations: + - Suggest `ed25519` for modern password authentication + - Suggest `unix_socket` for local root authentication +- Extended plugins support matrix (see [AUTHENTICATION_PLUGINS.md](documentation/AUTHENTICATION_PLUGINS.md)) ## MySQLTuner CVE vulnerabilities detection @@ -483,7 +542,7 @@ - **Storage Type**: Detects SSD/NVMe vs HDD by checking /sys/block/*/queue/rotational. - **Hardware Architecture**: Detects ARM64/Graviton vs x86_64. -- tuning Adjustments: Suggestions for innodb_flush_neighbors and innodb_io_capacity based on storage type. +- **Tuning Adjustments**: Suggestions for innodb_flush_neighbors and innodb_io_capacity based on storage type. ## MySQLTuner Cloud Autodiscovery @@ -506,3 +565,127 @@ - **JSON Snapshots**: Ingests JSON output from previous runs via --compare-file. - **Comparisons**: Provides trends for QPS and Data Growth between snapshots. + +## MySQLTuner Table Structure Analysis + +Activated with `--structstat` or `--verbose`. + +- Tables without primary keys detection +- Primary Key naming convention checks: + - Expected: `id` or `_id` + - Deviations flagged and counted +- Surrogate key type validation: + - Recommended: `BIGINT UNSIGNED AUTO_INCREMENT` + - UUID optimization: recommend `BINARY(16)` instead of `VARCHAR` +- Large tables (>1GB) without secondary indexes +- Foreign Key data type mismatches between referencing and referenced columns +- Non-InnoDB tables detection (recommend migration to InnoDB) +- Non-UTF8 columns detection (character set and collation audit) +- FULLTEXT columns inventory +- CSV export of findings (with --dumpdir): + - `tables_without_primary_keys.csv` + - `primary_key_issues.csv` + - `tables_non_innodb.csv` + - `columns_non_utf8.csv` + - `columns_utf8.csv` + - `fulltext_columns.csv` + +## MySQLTuner Naming Conventions Analysis + +Activated with `--structstat` or `--verbose`. + +- Automatic dominant style detection across the codebase: + - Supported styles: `snake_case`, `camelCase`, `PascalCase`, `kebab-case`, `UPPER_SNAKE_CASE` +- Table naming checks: + - Plural name detection (prefer singular table names) + - Casing consistency vs dominant style +- View naming consistency checks +- Index naming consistency checks +- Column naming checks: + - Casing consistency vs dominant style + - Boolean column prefix convention (`is_`, `has_`, `was_`, `had_`) + - Date/Time column suffix convention (`_at`, `_date`, `_time`) +- CSV export: `naming_convention_deviations.csv` (with --dumpdir) + +## MySQLTuner Foreign Key Analysis + +Activated with `--structstat` or `--verbose`. + +- Unconstrained `_id` columns: columns ending in `_id` that lack a FOREIGN KEY constraint +- FK actions audit: warns when `ON DELETE CASCADE` is used (potential data loss risk) +- FK type mismatches: data type differences between FK column and referenced column +- CSV export: `missing_foreign_keys.csv` (with --dumpdir) + +## MySQLTuner MySQL 8.0+ / MariaDB Modeling Checks + +Requires MySQL 8.0+ or MariaDB 10.x+. + +- JSON column indexability: + - Detects JSON columns without Virtual Generated Columns for indexing + - Recommends creating generated columns for frequently searched JSON attributes +- Invisible indexes detection: + - MySQL: `IS_VISIBLE = 'NO'` + - MariaDB: `IGNORED = 'YES'` +- CHECK constraints inventory (MySQL 8.0.16+) +- CSV export: `json_columns_without_virtual.csv` (with --dumpdir) + +## MySQLTuner Data Type Optimization + +Activated with `--structstat` or `--verbose`. + +- NULLability audit: warns when more than 20 columns have `IS_NULLABLE = 'YES'` +- Recommends using `NOT NULL` where possible for better performance and index efficiency + +## MySQLTuner Schema Sanitization + +Activated with `--structstat` or `--verbose`. + +- Empty schemas detection (no tables and no views) +- View-only schemas detection (views but no base tables) + +## MySQLTuner Weighted Health Score + +- Unified KPI aggregating findings across three dimensions: + - **Performance (40 points)**: + - Buffer Pool hit rate (10pts): >99% = 10, >95% = 5, else 0 + - Temp tables on disk (10pts): <10% = 10, <25% = 5, else 0 + - Thread cache hit rate (10pts): >90% = 10, >50% = 5, else 0 + - Connection usage (10pts): <80% = 10, else 0 + - **Security (30 points)**: + - Deducted for anonymous users, empty passwords, users without host restriction + - Deducted for insecure authentication plugins + - Deducted for missing SSL configuration + - **Resilience (30 points)**: + - Replication lag (10pts) + - Error log health (10pts) + - Metadata consistency (10pts) +- Color-coded display: Green (>80), Yellow (>50), Red (≤50) +- Stored in JSON output as `WeightedHealthScore` and `HealthScoreDetails` + +## MySQLTuner Predictive Capacity Analysis + +- **Memory Headroom**: + - Calculates theoretical peak memory usage vs available RAM+Swap + - Alerts when peak memory exceeds available resources (OOM risk) + - Reports headroom percentage of physical RAM +- **Disk Growth Forecasting**: + - Estimates daily data growth based on current total data size and server uptime + - Requires minimum 24 hours of uptime for reliable estimation +- Results stored in JSON: `Capacity.Memory.Peak`, `Capacity.Memory.Headroom`, `Capacity.Disk.DailyGrowth` + +## MySQLTuner Guided Auto-Fix Engine + +- Generates ready-to-apply SQL snippets from variable adjustment recommendations: + - **SET GLOBAL statements**: Immediate application without restart + - **[mysqld] configuration block**: For persistent my.cnf changes +- Only generated when variable adjustments are recommended +- Suppressed in `--silent` and `--json` modes + +## MySQLTuner Aborted Connections Management + +- Tracks aborted connections state across runs to avoid false positives +- State file protection: + - Symlink verification before read/write + - Atomic writes to prevent corruption + - Transport-specific host and container identifiers in state file path to prevent collisions +- Adjusts the aborted connections count to subtract connections caused by MySQLTuner's own password strength checks diff --git a/MEMORY_DB.md b/MEMORY_DB.md index 347f0cfb0..bfd407cf4 100644 --- a/MEMORY_DB.md +++ b/MEMORY_DB.md @@ -1,6 +1,6 @@ # MySQLTuner-perl Version Memory -## Current Version: 2.8.42 +## Current Version: 2.8.43 ## Project Evolution & Systemic Findings @@ -18,9 +18,12 @@ Migrated several external commands to native Core Perl to reduce fork overhead a - `uptime` -> `/proc/uptime` parsing or `$^T` calculation ### Recent Audits -- **v2.8.42**: - - Optimized `--dumpdir` analysis by skipping heavy views and AWS-specific metrics. - - Fixed fake aborted connections count increase when performing password strength checks (#900). +- **v2.8.43**: + - Added `--compress-dump` and `--dump-limit` options for schema exports. + - Exported deviations (naming conventions, foreign keys) to CSV and created manifest files. + - Prevented fake aborted connections count increase during password checking (#900). + - Resolved invalid credentials login errors, prevented plaintext password leakage, and protected connection state files. +- **v2.8.42**: Empty project metadata release. - **v2.8.41**: - Completed project-wide refactoring to use standard Perl Boolean practices. - Restored Debian maintenance account automatic login functionality (#896). diff --git a/Makefile b/Makefile index b25eb35ef..00baad6ba 100644 --- a/Makefile +++ b/Makefile @@ -73,6 +73,19 @@ generate_features: git add ./FEATURES.md git commit -m "docs: generate FEATURES.md" || echo "No changes to commit" +release: + @if [ -z "$(VERSION)" ]; then \ + echo "ERROR: VERSION is required. Usage: make release VERSION=X.XX.XX"; \ + exit 1; \ + fi + @OLD_VERSION=$$(cat CURRENT_VERSION.txt | tr -d '\n'); \ + echo "Bumping version from $$OLD_VERSION to $(VERSION)..."; \ + echo "$(VERSION)" > CURRENT_VERSION.txt; \ + sed -i "s/$$OLD_VERSION/$(VERSION)/g" mysqltuner.pl README.md POTENTIAL_ISSUES.md MEMORY_DB.md Changelog; \ + pod2markdown mysqltuner.pl > USAGE.md; \ + python3 build/release_gen.py; \ + echo "Version bumped to $(VERSION). USAGE.md and release notes generated." + increment_sub_version: @echo "Incrementing sub version from $(VERSION) to $(UPDATE_SUB_VERSION)" sed -i "s/$(VERSION)/$(UPDATE_SUB_VERSION)/" mysqltuner.pl *.md .github/workflows/*.yml @@ -129,6 +142,10 @@ test-all: vendor_setup @echo "Running all MySQLTuner Lab Tests..." bash build/test_envs.sh `perl build/get_supported_envs.pl` +test-parallel: vendor_setup + @echo "Running MySQLTuner Parallel Lab Tests..." + bash build/parallel_test.sh && $(MAKE) clean_examples KEEP=10 + test-container: @echo "Running MySQLTuner against container: $(CONTAINER)..." bash build/test_envs.sh -e "$(CONTAINER)" @@ -151,7 +168,7 @@ audit-logs: unit-tests: @echo "Running unit and regression tests..." - prove -r tests/ + perl ./build/audit_tests.pl clean_examples: @echo "Cleaning up examples..." diff --git a/POTENTIAL_ISSUES b/POTENTIAL_ISSUES deleted file mode 100644 index 8622e6c12..000000000 --- a/POTENTIAL_ISSUES +++ /dev/null @@ -1,178 +0,0 @@ -# POTENTIAL ISSUES AUDIT - -This file records anomalies discovered during laboratory testing (Perl warnings, SQL errors, etc.). - -## [2026-01-27 00:32] Session Start (v2.8.31) - -### Logic Anomalies - -- [x] **SQL Check Syntax Error**: `sh: 1: Syntax error: "(" unexpected` during `select CONCAT(...) from sys.schema_redundant_indexes`. - - Found in: MySQL 8.x and Percona 8.x laboratory logs. - - Fix: Escaped double quotes in `select_array` and `select_array_with_headers` to ensure safe transport in container mode. -- [x] **MariaDB LTS Stability**: Verified clean for 11.4, 10.11, 10.6. -- [x] **Performance Schema Disabled**: `Performance_schema should be activated.` reported during audit. Verified fix in lab tests. - - **How to fix**: - - **MySQL/MariaDB**: Add `performance_schema=ON` under `[mysqld]` in your `my.cnf` or `server.cnf` and restart the service. - - **Cloud/Managed**: Enable via your cloud provider console (e.g., AWS Parameter Group, GCP Flags). - - **Verification**: Run `SHOW VARIABLES LIKE 'performance_schema';` (should be `ON`). - -### Environment/Lab Issues - -- [x] **Laboratory Connection Failures**: Invalid credentials error `Attempted to use login credentials, but they were invalid` in targeted multi-version tests (mysql84, mysql80, mariadb1011, mariadb114). - - Impact: Integration tests failed to connect to the lab containers. - - Mitigation: Verified core logic via expanded unit tests (tests/core_logic_coverage.t) and cloud discovery tests (tests/cloud_discovery.t) while laboratory issues are investigated. -- [x] **MariaDB LTS Stability**: Verified clean for 11.4, 10.11, 10.6. - -Pre-existing anomalies found in examples/ directory: - -- SQL Execution Failure (return code 256) found in: - - examples/20260201_021412_mariadb118/Dumpdir/execution.log - - examples/20260201_021550_mysql84/Standard/execution.log - - examples/20260201_022737_mariadb118/Container/execution.log - - examples/20260201_021043_percona80/Standard/execution.log -- [x] **Perl Warnings (uninitialized value $opt{"colstat"})**: Fixed by normalizing CLI metadata key extraction in `%opt` hash. - - Found in: `examples/20260201_020318_mariadb1011/Standard/execution.log` etc. - - Fix: Stripped `Getopt::Long` modifiers (`!`, `+`, `=`, `:`) during `%opt` initialization and CLI parsing. - -## [2026-02-02 Audit] Release v2.8.35/v2.8.36 - -### [v2.8.35] Logic Anomalies - -- [x] **Perl Warning ($opt{"colstat"})**: `Use of uninitialized value $opt{"colstat"}` in MariaDB 10.11 and 10.6. - - Found in: `examples/20260202_231425_mariadb1011/Standard/execution.log` - - Fix: Normalized CLI primary key extraction to strip modifiers. Verified with `tests/cli_mod_keys.t`. - -### [v2.8.35] Environment/Lab Issues - -- [x] **SQL Execution Failure (return code 256)**: Persistent across MySQL 8.x, 9.6 and Percona 8.0. - - Found in: `examples/20260202_230352_mysql84/Standard/execution.log`, `examples/20260202_230050_mysql96/Standard/execution.log`. - - Fix: Issue #22 (Robust password column detection). - - Reproduce: `tests/repro_issue_22.t`. - -## [2026-02-02 Audit] System Call & Core Perl Optimization - -### Systemic Findings - -The following external commands are currently used via `execute_system_command` but have native Core Perl equivalents (no external dependencies required). Migrating these will reduce fork overhead and improve portability. - -#### High Priority Replacements (Low Complexity) - -- [x] **Command**: `whoami` (line 701) - - **Replacement**: `(getpwuid($<))[0]` (Native core Perl used). -- [x] **Command**: `env` / `printenv` (lines 1673, 1890, 1955) - - **Replacement**: Access the `%ENV` hash directly. -- [x] **Command**: `hostname` (line 3051) - - **Replacement**: `use Sys::Hostname; hostname();` (Core since Perl 5.6). -- [x] **Command**: `grep ... /proc/meminfo` (lines 1399, 1414, 3099) - - **Replacement**: Open `/proc/meminfo` and parse line-by-line (Core file handles). -- [x] **Command**: `grep -c ^processor /proc/cpuinfo` (line 949) - - **Replacement**: Open `/proc/cpuinfo` and count lines starting with `processor`. -- [x] **Command**: `which` (lines 1552, 1576) - - **Replacement**: Iterate through `split(/:/, $ENV{PATH})` and check file existence with `-x`. -- [x] **Command**: `getconf PAGESIZE` (line 2718) - - **Replacement**: `use POSIX; POSIX::sysconf(POSIX::_SC_PAGESIZE);` -- [x] **Command**: `uname` (lines 1108, 1395, 3044, 3049, 3117) - - **Replacement**: `use POSIX; POSIX::uname();` or `$^O`. - -#### Medium Priority Replacements (Environmental Specifics) - -- [x] **Command**: `stty -echo` / `stty echo` (lines 1701, 1925) - - **Replacement**: Use `POSIX::Termios` for terminal attribute control (avoids `stty` binary dependency). -- [x] **Command**: `uptime` (line 3107) - - **Replacement**: Read `/proc/uptime` (Linux-only) or calculate via `$^T` (script start time) for script uptime. System uptime requires `POSIX` / `/proc`. -- [ ] **Command**: `df` (lines 2790, 2791) - - **Replacement**: No cross-platform Core Perl replacement. Keep for now or use `statvfs` where available. -- [x] **Command**: `grep -Ec '^flags.*\ hypervisor\ ' /proc/cpuinfo` (line 2981) - - **Replacement**: Native Perl parsing of `/proc/cpuinfo`. -- [x] **Command**: `sysctl -n vm.swappiness` (line 3052) - - **Replacement**: Native Perl parsing of `/proc/sys/vm/swappiness`. - -## [2026-02-14 Audit] Release v2.8.38 - -### [v2.8.38] Environment/Lab Issues - -- [x] **SQL Execution Failure (return code 256)**: Persistent across MySQL 8.x and 9.x in laboratory reports. - - Found in: `examples/20260214_224108_mysql96/`, `examples/20260214_224539_mysql84/`. - - Symptom: `✘ FAIL Execute SQL / return code: 256`. - - Fix: Added safety check for `performance_schema` before `TRUNCATE TABLE performance_schema.host_cache` in `mysqltuner.pl`. -- [x] **Container Startup Failure**: `mysql96` failed to start during `make test-all`. - - Found in: `examples/20260214_234142_mysql96/`. - - Fix: Remapped Traefik dashboard port from 8080 to 8081 in `docker-compose.yml` to resolve host port conflict (verified). - - -## [2026-02-15 Audit] Development v2.8.40 - -### [v2.8.40] Environment/Lab Issues - -- [x] **SQL Execution Failure (return code 256)**: Persistent across MySQL 8.4 and 9.6 in laboratory reports. - - Found in: `examples/20260214_224108_mysql96/`, `examples/20260214_224539_mysql84/`. - - Symptom: `✘ FAIL Execute SQL / return code: 256`. - - Fix: Replaced brittle regex with `mysql_version_ge` for replication checks and corrected `FLUSH HOSTS` compatibility logic. -- [x] **Perl Warnings (uninitialized value in concatenation)**: Discovered during TDD for redo log logic improvements. - - Context: `mysql_innodb` uses `Innodb_log_write_requests` in `goodprint` strings. - - Mitigation: Refined test cases to mock essential stats and ensured logic handles undefined stats gracefully. - -## [2026-02-15 Audit] SSL/TLS & Cloud Enhancements - -### Logic Enhancements - -- [x] **SSL/TLS Security**: - - Added explicit TLS 1.2+ requirements. - - Added local certificate expiration audit (requires `openssl` and `date`). - - Added remote user SSL enforcement check. - - Verified with `tests/ssl_tls_validation.t`. -- [x] **Cloud Discovery**: - - Enhanced granularity for AWS (RDS vs Aurora), GCP (Cloud SQL), and Azure (Flexible vs Managed). - - Verified with improved `mysql_cloud_discovery` logic. - -### Quality Assurance - -- [ ] **Multi-Version Validation**: Pending `make test-it` execution across all lab environments. -- [ ] **Full Coverage Audit**: Identified 95 subroutines currently missing direct unit test coverage. - -## [2026-02-15 Audit] Session Update (v2.8.40) - -### 2026-02-15 Environment/Lab Issues - -- [x] **Systemic Container Failure (Exit code 1)**: Consistent failure across all database versions in `--container` mode. - - Found in: `examples/20260215_*/Container/execution.log`. - - Symptom: `OCI runtime exec failed: exec failed: unable to start container process: exec: "sh": executable file not found in $PATH`. - - Context: `get_container_prefix` uses `sh -c` which seems to fail in current lab containers. - - Fix: Verified as no longer reproducible in current `mysql96` lab tests; likely resolved upstream in container images. -- [x] **Audit Tool False Positives**: `build/audit_logs.pl` flags success messages containing the word "deprecated" as Perl warnings. - - Symptom: `✔ No users found using insecure or deprecated authentication plugins` is flagged. - - Fix: Refined regex in `audit_logs.pl` to safely exclude lines starting with `✔` or `[OK]`. - -### 2026-02-15 Quality Assurance - -- [x] **Unit Tests Stability**: 100% pass (53 files, 262 tests). -- [x] **Regression Cleanliness**: No new `uninitialized value` or `Syntax error` found in Standard, Dumpdir, or Schemadir scenarios. - -## [2026-05-17 Audit] Development v2.8.41 - -### [v2.8.41] Laboratory Verification - -- [x] **Older Perl Compatibility**: Verified that the script runs on Perl 5.6 and 5.8 without uninitialized value warnings or syntax errors. -- [x] **Dependency Audit**: Renovate updates for Docker actions and softprops/action-gh-release verified in CI pipelines. -- [x] **Idiomatic Boolean Refactoring**: Completed project-wide refactoring to use standard Perl Boolean practices (truthiness checks). - - Replaced `eq '0'`, `ne '0'`, `eq 0`, `ne 0`, `eq ""`, `ne ""` with truthy/falsy evaluations where appropriate. - - Refactored `%CLI_METADATA` defaults from `'0'` to `undef` for string/path options. - - Wrapped template reading logic in `get_template_model` to prevent `uninitialized value` warnings during `require`. - - Verified 100% test stability (262 tests passed). -- [x] **Zero-Warning Enforcement**: Fixed `removed_innodb_vars.t` mocking warnings and `mysql_80_modeling_checks` uninitialized values. Implemented strict Exit 1 policy on GitHub Actions CI. -- [x] **Dynamic CI Discovery**: Created perl wrapper to dynamically parse `mysql_support.md` and `mariadb_support.md` allowing testing configurations to be uncoupled from the `Makefile`. - -### 2026-04-29 Environment/Lab Issues - -- [x] **SQL Execution Failure**: Discovered during audit. - - Found in: `examples/20260429_112608_mysql96/Container/execution.log` (Line 10 and 12). - - Fix: MySQL 9.x `mysql` client removed support for `\G` and `\s` in batch mode (`-e`). Replaced `\G` with `-E` flag natively in `select_array` and `select_one_g`. Skipped error prints for `\s` if it fails natively. - -## [2026-05-25 Audit] Development v2.8.42 - -### [v2.8.42] Laboratory Verification - -- [x] **Unit Tests Stability**: 100% pass (54 files, 265 tests). -- [x] **Aborted Connections Counter Fix**: Verified via unit tests (`tests/test_issue_900.t`) that the fake aborted connections increase during password strength checking is successfully prevented. -- [x] **Dumpdir Exclusions**: Verified that heavy tables/views are successfully skipped to avoid query timeouts. - diff --git a/POTENTIAL_ISSUES.md b/POTENTIAL_ISSUES.md new file mode 100644 index 000000000..896c6c78c --- /dev/null +++ b/POTENTIAL_ISSUES.md @@ -0,0 +1,198 @@ +# POTENTIAL ISSUES AUDIT + +This file records anomalies discovered during laboratory testing (Perl warnings, SQL errors, etc.). + +## [2026-05-26 Audit] Massive Audit Campaign v2.8.43 + +### Unit Test Results + +- **Status**: ✅ ALL PASS +- **Files**: 69 test files +- **Assertions**: 346 tests +- **Perl Syntax**: Clean (`perl -cw mysqltuner.pl` — no warnings) + +### Test Coverage Analysis + +| Metric | Value | +|:---|:---| +| Total Subroutines | 165 | +| Tested Subroutines | ~91 (~55%) | +| Untested Subroutines | ~74 (~45%) | + +#### Key Untested Subroutines (High Priority) + +- `check_architecture`, `system_recommendations`, `mysql_indexes` +- `mysql_views`, `mysql_routines`, `mysql_triggers` +- `make_recommendations`, `close_outputfile`, `dump_result` +- `cloud_setup`, `get_ssh_prefix`, `get_container_prefix` +- `build_mysql_connection_command`, `select_csv_file` +- `write_manifest_files`, `get_tuning_info` + +### 🔴 Critical Issues + +#### PI-001: MySQL 8.0 EOL Status Incorrect +- **Source**: [mysql_support.md](file:///mysql_support.md) +- **Impact**: MySQL 8.0 reached EOL on 2026-04-30 but was listed as "Supported" +- **Status**: [x] **FIXED** — Updated to "Outdated" + +#### PI-002: SECURITY.md Stale Version Reference +- **Source**: [SECURITY.md](file:///SECURITY.md) line 11 +- **Impact**: Referenced v2.8.38 instead of current v2.8.43 +- **Status**: [x] **FIXED** — Updated to v2.8.43 + +#### PI-003: README.md Test Badge Wrong Repository +- **Source**: [README.md](file:///README.md) line 7 +- **Impact**: Test Status badge linked to `anuraghazra/github-readme-stats` instead of `jmrenouard/MySQLTuner-perl` +- **Status**: [x] **FIXED** — Updated to correct repository + +#### PI-004: README.md GitHub Stats Wrong User +- **Source**: [README.md](file:///README.md) line 43 +- **Impact**: GitHub stats image showed `anuraghazra` instead of `jmrenouard` +- **Status**: [x] **FIXED** — Updated to correct user + +#### PI-005: README.md Indicator Count Outdated +- **Source**: [README.md](file:///README.md) line 14 +- **Impact**: Claimed ~300 indicators but actual count is ~400+ +- **Status**: [x] **FIXED** — Updated to ~400 + +### 🟡 Medium Issues + +#### PI-006: 74 out of 165 subroutines have zero test coverage +- **Impact**: Functions like `check_architecture`, `system_recommendations`, `mysql_indexes`, `mysql_views`, `mysql_routines`, `mysql_triggers`, `make_recommendations`, `close_outputfile`, `dump_result` have no unit tests +- **Severity**: 🟡 MEDIUM — regression risk on core diagnostic functions +- **Coverage rate**: ~55% of subroutines referenced in at least one test + +#### PI-007: Extremely large subroutines +- **Impact**: Several functions exceed 500+ lines, making maintenance difficult +- **Functions to analyze**: `mysql_pfs` (1520 lines), `mysql_stats` (707), `mysql_innodb` (678), `execute_system_command` (565), `calculations` (492) +- **Severity**: 🟡 MEDIUM — SOLID SRP violation, but constrained by single-file architecture + +#### PI-008: `mysql_version_ge/le/eq` parse version on every call +- **Source**: Each call to `mysql_version_ge()`, `mysql_version_le()`, `mysql_version_eq()` re-parses `$myvar{'version'}` via regex +- **Impact**: Redundant computation — called 100+ times across the script +- **Severity**: 🟢 LOW — performance impact minimal but code duplication + +#### PI-009: MariaDB 10.6 Approaching EOL +- **Source**: [mariadb_support.md](file:///mariadb_support.md) +- **Impact**: MariaDB 10.6 LTS EOL is 2026-07-06 (41 days away) +- **Severity**: 🟡 MEDIUM — plan deprecation proactively + +#### PI-010: ROADMAP Phase 5 Status Incorrect +- **Source**: [ROADMAP.md](file:///ROADMAP.md) line 84 +- **Impact**: I/O Pressure & Flushing Advisor marked `[/]` but only basic `innodb_io_capacity` references exist — no flushing advisor implemented +- **Status**: [ ] Needs correction to `[ ]` + +### 🟢 Low Issues + +#### PI-011: No implementation for ROADMAP Phase 5 (Deep Engine Tuning) +- Read-Ahead Efficiency: 0 references +- Deadlock Analytics: 0 references +- Storage Alignment (doublewrite_pages, fdatasync): 0 references +- NUMA-Aware: 0 references +- Purge Lag (history_list_length): 0 references +- **Status**: Phase 5 is entirely unimplemented + +#### PI-012: No implementation for ROADMAP Phase 6 (InnoDB Cluster) +- Group Replication: 0 references +- **Status**: Phase 6 is entirely unimplemented + +#### PI-013: Partial ROADMAP Phase 7 (Replication) +- GTID mode: 7 references (basic checks exist) +- Binary log compression audit: not implemented +- Parallel applier tuning: not implemented +- Semi-sync safety check: not implemented +- **Status**: Phase 7 is partially implemented + +#### PI-014: ROADMAP Phase 8 (Galera) — Partially covered by existing Galera code +- wsrep references: 106 +- galera references: 51 +- But streaming replication audit, gcache optimization, certification failure deep-dive are NOT implemented +- **Status**: Phase 8 foundation exists, advanced diagnostics missing + +#### PI-015: ROADMAP Phase 9 (Data Integrity) — Partial +- innodb_checksum_algorithm: 5 references (basic check exists) +- innodb_log_checksums: 5 references (basic check exists) +- Binlog checksum, doublewrite consistency: NOT implemented +- **Status**: Phase 9 partially implemented + +#### PI-016: ROADMAP Phases 10-12 — Not started +- Workload Analysis & Traffic Profiling: Not implemented +- Advanced Log Parser & Lock Monitoring: Not implemented +- Sectional Global Indicators: Not implemented + +#### PI-017: ROADMAP Phase 13 (Export Optimization) — COMPLETED ✅ + +--- + +## [2026-05-26 Audit] Security Posture Assessment + +### Overall Posture: ✅ GOOD + +| Category | Status | +|:---|:---| +| Shell Injection Surface | 🟡 Mitigated by `execute_system_command` wrapper | +| Backtick Usage | ✅ No raw backticks outside wrapper | +| eval Usage | ✅ No dangerous patterns | +| File Operations | ✅ Proper handle usage | +| system()/exec() | ✅ No direct calls | +| Credential Handling | ✅ Properly masked in v2.8.43 | +| Temp File Safety | ✅ Symlink protection + atomic writes | +| SQL Injection | ✅ No user-controlled SQL interpolation | + +### Security Observations (Audit-Only) + +- S-001: `$mysqllogin` interpolated into shell commands — mitigated by quoting in v2.8.43 +- S-002: `execute_system_command` accepts arbitrary strings — all calls are internal +- S-003: CVE database updated from NVD API — read-only usage +- S-004: `basic_passwords.txt` shipped in repo — by design for detection +- S-005: No HTTPS certificate verification in `get_http_cli` — version check only + +--- + +## Historical Audit Log + +### [2026-01-27] Session Start (v2.8.31) + +- [x] **SQL Check Syntax Error**: Fixed escaped double quotes in `select_array`. +- [x] **MariaDB LTS Stability**: Verified clean for 11.4, 10.11, 10.6. +- [x] **Performance Schema Disabled**: Fixed and verified. +- [x] **Laboratory Connection Failures**: Verified via expanded unit tests. +- [x] **Perl Warnings ($opt{"colstat"})**: Fixed by normalizing CLI metadata key extraction. + +### [2026-02-02] Release v2.8.35/v2.8.36 + +- [x] **Perl Warning ($opt{"colstat"})**: Normalized CLI primary key extraction. +- [x] **SQL Execution Failure (return code 256)**: Fixed password column detection. + +### [2026-02-02] System Call & Core Perl Optimization + +- [x] All high-priority external commands replaced with native Perl (whoami, env, hostname, grep, which, getconf, uname) +- [x] All medium-priority commands addressed (stty, uptime, df, cpuinfo flags, sysctl) + +### [2026-02-14] Release v2.8.38 + +- [x] **SQL Execution Failure**: Added safety check for performance_schema. +- [x] **Container Startup Failure**: Remapped Traefik dashboard port. + +### [2026-02-15] Development v2.8.40 + +- [x] **SQL Execution Failure**: Replaced brittle regex with `mysql_version_ge`. +- [x] **Perl Warnings**: Refined test mocks for undefined stats. +- [x] **SSL/TLS Security**: Added TLS 1.2+ requirements and certificate audit. +- [x] **Cloud Discovery**: Enhanced granularity for AWS, GCP, Azure. +- [x] **Systemic Container Failure**: Resolved upstream in container images. +- [x] **Audit Tool False Positives**: Refined regex exclusions. + +### [2026-05-17] Development v2.8.41 + +- [x] **Older Perl Compatibility**: Verified Perl 5.6 and 5.8. +- [x] **Idiomatic Boolean Refactoring**: Completed project-wide. +- [x] **Zero-Warning Enforcement**: Fixed mock warnings and CI policy. +- [x] **Dynamic CI Discovery**: Created perl wrapper for support files. +- [x] **SQL Execution Failure (MySQL 9.x)**: Updated batch execution flags. + +### [2026-05-25] Development v2.8.43 + +- [x] **Unit Tests Stability**: 100% pass (69 files, 346 tests). +- [x] **Aborted Connections Counter Fix**: Verified via unit tests. +- [x] **Dumpdir Exclusions**: Heavy tables/views skipped. diff --git a/README.fr.md b/README.fr.md index fff55aac1..b6f955f46 100644 --- a/README.fr.md +++ b/README.fr.md @@ -3,14 +3,14 @@ [!["Offrez-nous un café"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/jmrenouard) [![État du projet](https://opensource.box.com/badges/active.svg)](https://opensource.box.com/badges) -[![État des tests](https://github.com/anuraghazra/github-readme-stats/workflows/Test/badge.svg)](https://github.com/anuraghazra/github-readme-stats/) +[![État des tests](https://github.com/jmrenouard/MySQLTuner-perl/workflows/Test/badge.svg)](https://github.com/jmrenouard/MySQLTuner-perl/actions) [![Temps moyen de résolution d'un problème](https://isitmaintained.com/badge/resolution/jmrenouard/MySQLTuner-perl.svg)](https://isitmaintained.com/project/jmrenouard/MySQLTuner-perl "Temps moyen de résolution d'un problème") [![Pourcentage de problèmes ouverts](https://isitmaintained.com/badge/open/jmrenouard/MySQLTuner-perl.svg)](https://isitmaintained.com/project/jmrenouard/MySQLTuner-perl "Pourcentage de problèmes encore ouverts") [![Licence GPL](https://badges.frapsoft.com/os/gpl/gpl.png?v=103)](https://opensource.org/licenses/GPL-3.0/) **MySQLTuner** est un script écrit en Perl qui vous permet d'examiner rapidement une installation MySQL et de faire des ajustements pour augmenter les performances et la stabilité. Les variables de configuration actuelles et les données d'état sont récupérées et présentées dans un bref format avec quelques suggestions de performances de base. -**MySQLTuner** prend en charge environ 300 indicateurs et KPI (y compris le score de santé pondéré) pour MySQL/MariaDB/Percona Server dans cette dernière version. +**MySQLTuner** prend en charge environ 900+ indicateurs, KPI et recommandations (y compris le score de santé pondéré, la planification prédictive des capacités et l'audit SSL/TLS) pour MySQL/MariaDB/Percona Server dans cette dernière version. **MySQLTuner** est activement maintenu et prend en charge de nombreuses configurations telles que [Galera Cluster](https://galeracluster.com/), [TokuDB](https://www.percona.com/software/mysql-database/percona-tokudb), [Schéma de performance](https://github.com/mysql/mysql-sys), les métriques du système d'exploitation Linux, [InnoDB](https://dev.mysql.com/doc/refman/5.7/en/innodb-storage-engine.html), [MyISAM](https://dev.mysql.com/doc/refman/5.7/en/myisam-storage-engine.html), [Aria](https://mariadb.com/docs/server/server-usage/storage-engines/aria/aria-storage-engine), ... @@ -38,7 +38,7 @@ MySQLTuner a besoin de vous * Support payant pour LightPath ici : [jmrenouard@lightpath.fr](jmrenouard@lightpath.fr) * Support payant pour Releem disponible ici : [Application Releem](https://releem.com/) -![Statistiques GitHub d'Anurag](https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&theme=radical) +![Statistiques GitHub de jmrenouard](https://github-readme-stats.vercel.app/api?username=jmrenouard&show_icons=true&theme=radical) ## Stargazers au fil du temps @@ -71,10 +71,19 @@ Merci à [endoflife.date](https://endoflife.date/) ***Intelligence avancée et écosystème*** -* **Indicateur de score de santé pondéré (KPI)** : Évaluation globale de la santé de la base de données basée sur les performances, la sécurité et la résilience. -* **Conseiller en migration intelligente LTS** : Identification des risques lors de la migration vers les versions LTS modernes (MySQL 8.4/9.0+, MariaDB 11.x). -* **Planification prédictive des capacités** : Analyse de la marge de manœuvre de la mémoire et prévision de la croissance du disque. -* **Découverte du Cloud** : prise en charge native d'AWS RDS/Aurora, GCP Cloud SQL, Azure (Flexible/Managed) et DigitalOcean. +* **Indicateur de score de santé pondéré (KPI)** : Évaluation globale de la santé de la base de données (0-100) basée sur les performances (40pts), la sécurité (30pts) et la résilience (30pts). +* **Conseiller en migration intelligente LTS** : Identification des risques lors de la migration vers les versions LTS modernes (MySQL 8.4/9.0+, MariaDB 11.x), incluant les variables supprimées et les méthodes d'authentification dépréciées. +* **Planification prédictive des capacités** : Analyse de la marge de manœuvre mémoire (pic vs RAM+Swap disponible), prévision de la croissance disque, et détection de la capacité AUTO_INCREMENT proche du maximum. +* **Découverte automatique du Cloud** : Prise en charge native d'AWS RDS/Aurora, GCP Cloud SQL, Azure (Flexible/Managed) et DigitalOcean. Détection automatique via `@@version_comment` et variables spécifiques au fournisseur. +* **Tuning adaptatif à l'infrastructure** : Détection des types de stockage SSD/NVMe vs HDD et des architectures ARM64/Graviton vs x86_64. Ajustement des recommandations pour `innodb_flush_neighbors` et `innodb_io_capacity`. +* **Audit de sécurité SSL/TLS** : Vérification du chiffrement de session, audit des versions TLS (alerte sur TLSv1.0/1.1), expiration des certificats, application de `require_secure_transport`, et vérification SSL des utilisateurs distants. +* **Audit des plugins d'authentification** : Détection des plugins non sécurisés (`mysql_native_password`, `sha256_password`), diagnostic de compatibilité MySQL 9.x, et recommandations MariaDB `ed25519`/`unix_socket`. +* **Modélisation de schéma et conventions de nommage** : Analyse complète de la structure des tables (PK manquantes, types de clés de substitution, conformité UTF-8, tables non-InnoDB), audit des conventions de nommage (cohérence snake_case/camelCase, détection du pluriel, préfixes de colonnes booléennes/dates), et analyse des clés étrangères (colonnes `_id` non contraintes, incohérences de types, audit CASCADE). +* **Modélisation MySQL 8.0+ / MariaDB** : Indexabilité des colonnes JSON (colonnes virtuelles générées), index invisibles, contraintes CHECK. +* **Moteur Auto-Fix guidé** : Génération d'instructions `SET GLOBAL` SQL prêtes à l'emploi et de blocs de configuration `[mysqld]` à partir des recommandations d'ajustement de variables. +* **Analyse de tendances historiques** : Ingestion de sorties JSON de runs précédents via `--compare-file` pour suivre les tendances QPS et de croissance des données. +* **Intégration Sysbench** : Analyse de la sortie sysbench pour les métriques QPS, TPS et latence (Moy/95e/Max) via `--sysbench-file`. +* **Intégration logs Container et Systemd** : Détection automatique des logs depuis Docker, Podman, Kubectl/Kubernetes et le journal Systemd. ***Moteurs de stockage non pris en charge : les PR sont les bienvenues*** -- @@ -154,6 +163,22 @@ Que vérifie exactement MySQLTuner ? Toutes les vérifications effectuées par **MySQLTuner** sont documentées dans la documentation [MySQLTuner Internals](https://github.com/jmrenouard/MySQLTuner-perl/blob/master/INTERNALS.md). +**MySQLTuner** analyse les domaines suivants : + +* **Système et OS** : RAM, swap, ports ouverts, paramètres noyau, charge, points de montage, cartes réseau +* **Version du serveur** : Détection EOL, architecture, recommandations 64 bits +* **Logs d'erreur** : Fichiers locaux, conteneurs Docker/Podman, pods Kubernetes, journal Systemd +* **Cloud et Infrastructure** : AWS RDS/Aurora, GCP, Azure, DigitalOcean ; SSD/NVMe vs HDD ; ARM64/x86_64 +* **Moteurs de stockage** : InnoDB (buffer pool, redo log, chunk size), MyISAM, Aria, Galera, TokuDB, RocksDB +* **Sécurité** : Utilisateurs anonymes, mots de passe faibles, audit SSL/TLS, plugins d'authentification, vulnérabilités CVE +* **Connexions** : Pourcentages d'utilisation, connexions abandonnées, cache de threads +* **Performance** : Tri/jointures/tables temporaires, buffers globaux, cache de requêtes, requêtes lentes, utilisation mémoire +* **Réplication** : État Source/Réplica, retard, GTID, semi-sync, multi-source +* **Performance Schema** : Top utilisateurs/hôtes/requêtes, latence IO, verrouillages, index inutilisés, index redondants +* **Modélisation de schéma** : Analyse des clés primaires, conventions de nommage, clés étrangères, types de données, conformité UTF-8, indexabilité JSON +* **Prédictif** : Marge mémoire, prévision de croissance disque, capacité AUTO_INCREMENT +* **Score de santé** : KPI pondéré (0-100) agrégant les résultats Performance, Sécurité et Résilience + Téléchargement/Installation -- @@ -373,6 +398,73 @@ perl mysqltuner.pl --debug perl mysqltuner.pl --checkversion --updateversion ``` +**Utilisation :** Intégration des résultats de performance Sysbench + +```bash +perl mysqltuner.pl --sysbench-file=/chemin/vers/sortie_sysbench.txt +``` + +**Utilisation :** Analyse de tendances historiques (comparaison avec un run précédent) + +```bash +perl mysqltuner.pl --json --outputfile=run1.json +# ... quelque temps plus tard ... +perl mysqltuner.pl --compare-file=run1.json +``` + +**Utilisation :** Exporter un fichier Markdown par schéma (documentation de schéma) + +```bash +perl mysqltuner.pl --verbose --schemadir=./schemas +``` + +**Utilisation :** Export de données avec limite de lignes et compression gzip + +```bash +perl mysqltuner.pl --verbose --dumpdir=./result --dump-limit=10000 --compress-dump +``` + +**Utilisation :** Mode conteneur (analyser une base de données dans Docker) + +```bash +perl mysqltuner.pl --verbose --container docker:nom_du_conteneur_mysql +``` + +**Utilisation :** Analyse de structure de table et conventions de nommage + +```bash +perl mysqltuner.pl --structstat +``` + +**Utilisation :** Filtrer la sortie (afficher uniquement les problèmes) + +```bash +perl mysqltuner.pl --nogood --noinfo +``` + +**Utilisation :** Sortie JSON (pour l'automatisation et les pipelines de reporting) + +```bash +perl mysqltuner.pl --json --outputfile=report.json +perl mysqltuner.pl --prettyjson +``` + +**Utilisation :** Mode serveur non dédié (hébergement partagé) + +```bash +perl mysqltuner.pl --nondedicated +``` + +**Utilisation :** Utiliser des identifiants via des variables d'environnement + +```bash +export MYSQL_USER=mysqltuner +export MYSQL_PASS=secret +perl mysqltuner.pl --userenv=MYSQL_USER --passenv=MYSQL_PASS +``` + +Pour une liste complète de toutes les options disponibles, exécutez `perl mysqltuner.pl --help` ou consultez la documentation [USAGE.md](https://github.com/jmrenouard/MySQLTuner-perl/blob/master/USAGE.md). + Prise en charge du cloud -- @@ -604,7 +696,7 @@ wget https://raw.githubusercontent.com/jmrenouard/MySQLTuner-perl/master/vulnera chmod +x mysqltuner.pl ``` -* **Git clone :** +* **Git clone :** ```bash git clone --depth 1 -b master https://github.com/jmrenouard/MySQLTuner-perl.git @@ -612,73 +704,35 @@ cd MySQLTuner-perl perl mysqltuner.pl ``` -* **Environnements isolés (air-gapped) :** Si votre serveur ne dispose pas d'un accès direct à Internet, téléchargez les fichiers ci-dessus sur un hôte disposant d'un accès Internet (ou via un proxy), puis transférez `mysqltuner.pl`, `basic_passwords.txt` et `vulnerabilities.csv` sur le serveur cible via `scp`, `rsync` ou toute autre méthode de transfert de fichiers. +* **Environnements isolés (air-gapped) :** Si votre serveur ne dispose pas d'un accès direct à Internet, téléchargez les fichiers ci-dessus sur un hôte disposant d'un accès Internet (ou via un proxy), puis transférez `mysqltuner.pl`, `basic_passwords.txt` et `vulnerabilities.csv` sur le serveur cible via `scp`, `rsync` ou toute autre méthode de transfert de fichiers. -MySQLTuner et Vagrant +MySQLTuner et Vagrant (Héritage) -- -**MySQLTuner** contient les configurations Vagrant suivantes : - -* Fedora Core 30 / Docker +> **Note :** L'environnement de test basé sur Vagrant est considéré comme héritage. Pour les tests modernes, utilisez la suite de tests basée sur Docker via `make test-it` ou `build/test_envs.sh`. **Le fichier Vagrant** est stocké dans le sous-répertoire Vagrant. -* Suivez les étapes suivantes après l'installation de Vagrant : - $ vagrant up - -**MySQLTuner** contient une configuration Vagrant à des fins de test et de développement - -* Installez VirtualBox et Vagrant - * - * -* Clonez le dépôt - * git clone -* Installez les plugins Vagrant vagrant-hostmanager et vagrant-vbguest - * vagrant plugin install vagrant-hostmanager - * vagrant plugin install vagrant-vbguest -* Ajoutez la boîte Fedora Core 30 depuis le site de téléchargement officiel de Fedora - * vagrant box add --name generic/fedora30 -* Créez un répertoire de données - * mkdir data - -## configurer les environnements de test - - $ sh build/createTestEnvs.sh - - $ source build/bashrc - $ mysql_percona80 sakila - sakila> ... - - $ docker images - mariadb 10.1 fc612450e1f1 12 days ago 352MB - mariadb 10.2 027b7c57b8c6 12 days ago 340MB - mariadb 10.3 47dff68107c4 12 days ago 343MB - mariadb 10.4 92495405fc36 12 days ago 356MB - mysql 5.6 95e0fc47b096 2 weeks ago 257MB - mysql 5.7 383867b75fd2 2 weeks ago 373MB - mysql 8.0 b8fd9553f1f0 2 weeks ago 445MB - percona/percona-server 5.7 ddd245ed3496 5 weeks ago 585MB - percona/percona-server 5.6 ed0a36e0cf1b 6 weeks ago 421MB - percona/percona-server 8.0 390ae97d57c6 6 weeks ago 697MB - mariadb 5.5 c7bf316a4325 4 months ago 352MB - mariadb 10.0 d1bde56970c6 4 months ago 353MB - mysql 5.5 d404d78aa797 4 months ago 205MB - - $ docker ps - CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES - da2be9b050c9 mariadb:5.5 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5311->3306/tcp mariadb55 - 5deca25d5ac8 mariadb:10.0 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5310->3306/tcp mariadb100 - 73aaeb37e2c2 mariadb:10.1 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5309->3306/tcp mariadb101 - 72ffa77e01ec mariadb:10.2 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5308->3306/tcp mariadb102 - f5996f2041df mariadb:10.3 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5307->3306/tcp mariadb103 - 4890c52372bb mariadb:10.4 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5306->3306/tcp mariadb104 - 6b9dc078e921 percona/percona-server:5.6 "/docker-entrypoint.…" 7 hours ago Up 7 hours 0.0.0.0:4308->3306/tcp percona56 - 3a4c7c826d4c percona/percona-server:5.7 "/docker-entrypoint.…" 7 hours ago Up 7 hours 0.0.0.0:4307->3306/tcp percona57 - 3dda408c91b0 percona/percona-server:8.0 "/docker-entrypoint.…" 7 hours ago Up 7 hours 33060/tcp, 0.0.0.0:4306->3306/tcp percona80 - 600a4e7e9dcd mysql:5.5 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:3309->3306/tcp mysql55 - 4bbe54342e5d mysql:5.6 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:3308->3306/tcp mysql56 - a49783249a11 mysql:5.7 "docker-entrypoint.s…" 7 hours ago Up 7 hours 33060/tcp, 0.0.0.0:3307->3306/tcp mysql57 - d985820667c2 mysql:8.0 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:3306->3306/tcp, 33060/tcp mysql 8 0 +## Configuration des environnements de test Docker + +MySQLTuner inclut une infrastructure de test basée sur Docker pour la validation multi-versions : + +```bash +# Créer et démarrer tous les conteneurs de test +sh build/createTestEnvs.sh + +# Charger les aides d'environnement +source build/bashrc + +# Se connecter à une base de données spécifique +mysql_percona80 sakila +``` + +**Cibles de test prises en charge** (reportez-vous à [support MariaDB](mariadb_support.md) et [support MySQL](mysql_support.md) pour la matrice de compatibilité actuelle) : + +* MySQL 8.0, 8.4, 9.x +* MariaDB 10.6, 10.11, 11.4, 11.8 +* Percona Server 8.0 Les contributions sont les bienvenues -- diff --git a/README.it.md b/README.it.md index 7adcc86c7..d5175f737 100644 --- a/README.it.md +++ b/README.it.md @@ -3,14 +3,14 @@ [!["Offrici un caffè"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/jmrenouard) [![Stato del progetto](https://opensource.box.com/badges/active.svg)](https://opensource.box.com/badges) -[![Stato dei test](https://github.com/anuraghazra/github-readme-stats/workflows/Test/badge.svg)](https://github.com/anuraghazra/github-readme-stats/) +[![Stato dei test](https://github.com/jmrenouard/MySQLTuner-perl/workflows/Test/badge.svg)](https://github.com/jmrenouard/MySQLTuner-perl/actions) [![Tempo medio per risolvere un problema](https://isitmaintained.com/badge/resolution/jmrenouard/MySQLTuner-perl.svg)](https://isitmaintained.com/project/jmrenouard/MySQLTuner-perl "Tempo medio per risolvere un problema") [![Percentuale di problemi aperti](https://isitmaintained.com/badge/open/jmrenouard/MySQLTuner-perl.svg)](https://isitmaintained.com/project/jmrenouard/MySQLTuner-perl "Percentuale di problemi ancora aperti") [![Licenza GPL](https://badges.frapsoft.com/os/gpl/gpl.png?v=103)](https://opensource.org/licenses/GPL-3.0/) **MySQLTuner** è uno script scritto in Perl che consente di esaminare rapidamente un'installazione di MySQL e apportare modifiche per aumentare le prestazioni e la stabilità. Le variabili di configurazione correnti e i dati di stato vengono recuperati e presentati in un formato breve insieme ad alcuni suggerimenti di base sulle prestazioni. -**MySQLTuner** supporta circa 300 indicatori e KPI (incluso il Weighted Health Score) per MySQL/MariaDB/Percona Server in quest'ultima versione. +**MySQLTuner** supporta circa 900+ indicatori, KPI e raccomandazioni (incluso il Weighted Health Score, la pianificazione predittiva della capacità e l'audit SSL/TLS) per MySQL/MariaDB/Percona Server in quest'ultima versione. **MySQLTuner** è attivamente mantenuto e supporta molte configurazioni come [Galera Cluster](https://galeracluster.com/), [TokuDB](https://www.percona.com/software/mysql-database/percona-tokudb), [Performance schema](https://github.com/mysql/mysql-sys), metriche del sistema operativo Linux, [InnoDB](https://dev.mysql.com/doc/refman/5.7/en/innodb-storage-engine.html), [MyISAM](https://dev.mysql.com/doc/refman/5.7/en/myisam-storage-engine.html), [Aria](https://mariadb.com/docs/server/server-usage/storage-engines/aria/aria-storage-engine), ... @@ -38,7 +38,7 @@ MySQLTuner ha bisogno di te * Supporto a pagamento per LightPath qui: [jmrenouard@lightpath.fr](jmrenouard@lightpath.fr) * Supporto a pagamento per Releem disponibile qui: [App Releem](https://releem.com/) -![Statistiche GitHub di Anurag](https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&theme=radical) +![Statistiche GitHub di jmrenouard](https://github-readme-stats.vercel.app/api?username=jmrenouard&show_icons=true&theme=radical) ## Stargazer nel tempo @@ -71,10 +71,19 @@ Grazie a [endoflife.date](https://endoflife.date/) ***Intelligenza Avanzata ed Ecosystem*** -* **Weighted Health Score KPI**: Valutazione complessiva della salute del database basata su prestazioni, sicurezza e resilienza. -* **Smart Migration LTS Advisor**: Identificazione dei rischi durante la migrazione a versioni LTS moderne (MySQL 8.4/9.0+, MariaDB 11.x). -* **Predictive Capacity Planning**: Analisi dell'headroom della memoria e previsione della crescita del disco. -* **Cloud Discovery**: supporto nativo per AWS RDS/Aurora, GCP Cloud SQL, Azure (Flexible/Managed) e DigitalOcean. +* **Weighted Health Score KPI**: Valutazione complessiva della salute del database (0-100) basata su prestazioni (40pts), sicurezza (30pts) e resilienza (30pts). +* **Smart Migration LTS Advisor**: Identificazione dei rischi durante la migrazione a versioni LTS moderne (MySQL 8.4/9.0+, MariaDB 11.x), incluse variabili rimosse e metodi di autenticazione deprecati. +* **Predictive Capacity Planning**: Analisi dell'headroom della memoria (picco vs RAM+Swap disponibile), previsione della crescita del disco e rilevamento della capacità AUTO_INCREMENT vicina al massimo. +* **Cloud Autodiscovery**: Supporto nativo per AWS RDS/Aurora, GCP Cloud SQL, Azure (Flexible/Managed) e DigitalOcean. Rilevamento automatico tramite `@@version_comment` e variabili specifiche del provider. +* **Tuning adattivo all'infrastruttura**: Rilevamento dei tipi di storage SSD/NVMe vs HDD e architetture ARM64/Graviton vs x86_64. Adeguamento delle raccomandazioni per `innodb_flush_neighbors` e `innodb_io_capacity`. +* **Audit di sicurezza SSL/TLS**: Verifica della crittografia della sessione, audit delle versioni TLS (avviso su TLSv1.0/1.1), scadenza dei certificati, applicazione di `require_secure_transport` e verifica SSL degli utenti remoti. +* **Audit dei plugin di autenticazione**: Rilevamento di plugin non sicuri (`mysql_native_password`, `sha256_password`), diagnostica di compatibilità MySQL 9.x e raccomandazioni MariaDB `ed25519`/`unix_socket`. +* **Modellazione dello schema e convenzioni di denominazione**: Analisi completa della struttura delle tabelle (PK mancanti, tipi di chiavi surrogate, conformità UTF-8, tabelle non-InnoDB), audit delle convenzioni di denominazione (coerenza snake_case/camelCase, rilevamento plurale, prefissi colonne booleane/date) e analisi delle chiavi esterne (colonne `_id` senza vincoli, disallineamenti di tipo, audit CASCADE). +* **Modellazione MySQL 8.0+ / MariaDB**: Indicizzabilità delle colonne JSON (colonne virtuali generate), indici invisibili, vincoli CHECK. +* **Motore Auto-Fix guidato**: Generazione di istruzioni `SET GLOBAL` SQL pronte all'uso e blocchi di configurazione `[mysqld]` dalle raccomandazioni di regolazione delle variabili. +* **Analisi delle tendenze storiche**: Ingestione dell'output JSON delle esecuzioni precedenti tramite `--compare-file` per monitorare le tendenze QPS e crescita dei dati. +* **Integrazione Sysbench**: Analisi dell'output sysbench per metriche QPS, TPS e latenza (Media/95°/Max) tramite `--sysbench-file`. +* **Integrazione log Container e Systemd**: Rilevamento automatico dei log da Docker, Podman, Kubectl/Kubernetes e journal Systemd. ***Motori di archiviazione non supportati: le PR sono benvenute*** -- @@ -154,6 +163,22 @@ Cosa sta controllando esattamente MySQLTuner? Tutti i controlli eseguiti da **MySQLTuner** sono documentati nella documentazione [MySQLTuner Internals](https://github.com/jmrenouard/MySQLTuner-perl/blob/master/INTERNALS.md). +**MySQLTuner** analizza le seguenti aree: + +* **Sistema e OS**: RAM, swap, porte aperte, parametri del kernel, carico medio, punti di montaggio, schede di rete +* **Versione del server**: Rilevamento EOL, architettura, raccomandazioni 64-bit +* **Log degli errori**: File locali, container Docker/Podman, pod Kubernetes, journal Systemd +* **Cloud e Infrastruttura**: AWS RDS/Aurora, GCP, Azure, DigitalOcean; SSD/NVMe vs HDD; ARM64/x86_64 +* **Motori di archiviazione**: InnoDB (buffer pool, redo log, chunk size), MyISAM, Aria, Galera, TokuDB, RocksDB +* **Sicurezza**: Utenti anonimi, password deboli, audit SSL/TLS, plugin di autenticazione, vulnerabilità CVE +* **Connessioni**: Percentuali di utilizzo, connessioni interrotte, cache dei thread +* **Prestazioni**: Ordinamento/join/tabelle temporanee, buffer globali, cache delle query, query lente, utilizzo della memoria +* **Replica**: Stato Source/Replica, ritardo, GTID, semi-sync, multi-source +* **Performance Schema**: Top utenti/host/query, latenza IO, lock wait, indici inutilizzati, indici ridondanti +* **Modellazione dello schema**: Analisi delle chiavi primarie, convenzioni di denominazione, chiavi esterne, tipi di dati, conformità UTF-8, indicizzabilità JSON +* **Predittivo**: Headroom di memoria, previsione di crescita del disco, capacità AUTO_INCREMENT +* **Punteggio di salute**: KPI ponderato (0-100) che aggrega i risultati di Prestazioni, Sicurezza e Resilienza + Download/Installazione -- @@ -373,6 +398,65 @@ perl mysqltuner.pl --debug perl mysqltuner.pl --checkversion --updateversion ``` +**Utilizzo:** Integrazione dei risultati di prestazioni Sysbench + +```bash +perl mysqltuner.pl --sysbench-file=/percorso/verso/output_sysbench.txt +``` + +**Utilizzo:** Analisi delle tendenze storiche (confronto con un'esecuzione precedente) + +```bash +perl mysqltuner.pl --json --outputfile=run1.json +# ... qualche tempo dopo ... +perl mysqltuner.pl --compare-file=run1.json +``` + +**Utilizzo:** Esporta un file Markdown per schema (documentazione dello schema) + +```bash +perl mysqltuner.pl --verbose --schemadir=./schemas +``` + +**Utilizzo:** Export dei dati con limite di righe e compressione gzip + +```bash +perl mysqltuner.pl --verbose --dumpdir=./result --dump-limit=10000 --compress-dump +``` + +**Utilizzo:** Modalità container (analizzare un database in Docker) + +```bash +perl mysqltuner.pl --verbose --container docker:nome_del_container_mysql +``` + +**Utilizzo:** Analisi della struttura delle tabelle e convenzioni di denominazione + +```bash +perl mysqltuner.pl --structstat +``` + +**Utilizzo:** Filtra l'output (mostra solo i problemi) + +```bash +perl mysqltuner.pl --nogood --noinfo +``` + +**Utilizzo:** Output JSON (per l'automazione e le pipeline di reporting) + +```bash +perl mysqltuner.pl --json --outputfile=report.json +perl mysqltuner.pl --prettyjson +``` + +**Utilizzo:** Modalità server non dedicato (hosting condiviso) + +```bash +perl mysqltuner.pl --nondedicated +``` + +Per un elenco completo di tutte le opzioni disponibili, esegui `perl mysqltuner.pl --help` o consulta la documentazione [USAGE.md](https://github.com/jmrenouard/MySQLTuner-perl/blob/master/USAGE.md). + Supporto cloud -- @@ -614,71 +698,33 @@ perl mysqltuner.pl * **Ambienti isolati (air-gapped):** Se il tuo server non ha accesso diretto a Internet, scarica i file su un host con accesso a Internet (o tramite un proxy), quindi trasferisci `mysqltuner.pl`, `basic_passwords.txt` e `vulnerabilities.csv` al server di destinazione tramite `scp`, `rsync` o un altro metodo di trasferimento file. -MySQLTuner e Vagrant +MySQLTuner e Vagrant (Legacy) -- -**MySQLTuner** contiene le seguenti configurazioni di Vagrant: - -* Fedora Core 30 / Docker +> **Nota:** L'ambiente di test basato su Vagrant è considerato legacy. Per i test moderni, utilizza la suite di test basata su Docker tramite `make test-it` o `build/test_envs.sh`. **Il file Vagrant** è archiviato nella sottodirectory Vagrant. -* Segui i seguenti passaggi dopo l'installazione di Vagrant: - $ vagrant up - -**MySQLTuner** contiene una configurazione Vagrant per scopi di test e sviluppo - -* Installa VirtualBox e Vagrant - * - * -* Clona il repository - * git clone -* Installa i plugin di Vagrant vagrant-hostmanager e vagrant-vbguest - * vagrant plugin install vagrant-hostmanager - * vagrant plugin install vagrant-vbguest -* Aggiungi la box di Fedora Core 30 dal sito Web di download ufficiale di Fedora - * vagrant box add --name generic/fedora30 -* Crea una directory di dati - * mkdir data - -## configura ambienti di test - - $ sh build/createTestEnvs.sh - - $ source build/bashrc - $ mysql_percona80 sakila - sakila> ... - - $ docker images - mariadb 10.1 fc612450e1f1 12 days ago 352MB - mariadb 10.2 027b7c57b8c6 12 days ago 340MB - mariadb 10.3 47dff68107c4 12 days ago 343MB - mariadb 10.4 92495405fc36 12 days ago 356MB - mysql 5.6 95e0fc47b096 2 weeks ago 257MB - mysql 5.7 383867b75fd2 2 weeks ago 373MB - mysql 8.0 b8fd9553f1f0 2 weeks ago 445MB - percona/percona-server 5.7 ddd245ed3496 5 weeks ago 585MB - percona/percona-server 5.6 ed0a36e0cf1b 6 weeks ago 421MB - percona/percona-server 8.0 390ae97d57c6 6 weeks ago 697MB - mariadb 5.5 c7bf316a4325 4 months ago 352MB - mariadb 10.0 d1bde56970c6 4 months ago 353MB - mysql 5.5 d404d78aa797 4 months ago 205MB - - $ docker ps - CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES - da2be9b050c9 mariadb:5.5 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5311->3306/tcp mariadb55 - 5deca25d5ac8 mariadb:10.0 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5310->3306/tcp mariadb100 - 73aaeb37e2c2 mariadb:10.1 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5309->3306/tcp mariadb101 - 72ffa77e01ec mariadb:10.2 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5308->3306/tcp mariadb102 - f5996f2041df mariadb:10.3 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5307->3306/tcp mariadb103 - 4890c52372bb mariadb:10.4 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5306->3306/tcp mariadb104 - 6b9dc078e921 percona/percona-server:5.6 "/docker-entrypoint.…" 7 hours ago Up 7 hours 0.0.0.0:4308->3306/tcp percona56 - 3a4c7c826d4c percona/percona-server:5.7 "/docker-entrypoint.…" 7 hours ago Up 7 hours 0.0.0.0:4307->3306/tcp percona57 - 3dda408c91b0 percona/percona-server:8.0 "/docker-entrypoint.…" 7 hours ago Up 7 hours 33060/tcp, 0.0.0.0:4306->3306/tcp percona80 - 600a4e7e9dcd mysql:5.5 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:3309->3306/tcp mysql55 - 4bbe54342e5d mysql:5.6 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:3308->3306/tcp mysql56 - a49783249a11 mysql:5.7 "docker-entrypoint.s…" 7 hours ago Up 7 hours 33060/tcp, 0.0.0.0:3307->3306/tcp mysql57 - d985820667c2 mysql:8.0 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:3306->3306/tcp, 33060/tcp mysql 8 0 +## Configurazione degli ambienti di test Docker + +MySQLTuner include un'infrastruttura di test basata su Docker per la validazione multi-versione: + +```bash +# Crea e avvia tutti i container di test +sh build/createTestEnvs.sh + +# Carica gli helper dell'ambiente +source build/bashrc + +# Connettiti a un database specifico +mysql_percona80 sakila +``` + +**Target di test supportati** (fare riferimento a [supporto MariaDB](mariadb_support.md) e [supporto MySQL](mysql_support.md) per la matrice di compatibilità attuale): + +* MySQL 8.0, 8.4, 9.x +* MariaDB 10.6, 10.11, 11.4, 11.8 +* Percona Server 8.0 I contributi sono benvenuti -- diff --git a/README.md b/README.md index 88114d80e..76b123cad 100644 --- a/README.md +++ b/README.md @@ -3,15 +3,15 @@ [!["Buy Us A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/jmrenouard) [![Project Status](https://opensource.box.com/badges/active.svg)](https://opensource.box.com/badges) -[![MySQLTuner Version](https://img.shields.io/badge/version-2.8.42-blue.svg)](https://github.com/jmrenouard/MySQLTuner-perl/releases/tag/v2.8.42) -[![Test Status](https://github.com/anuraghazra/github-readme-stats/workflows/Test/badge.svg)](https://github.com/anuraghazra/github-readme-stats/) +[![MySQLTuner Version](https://img.shields.io/badge/version-2.8.43-blue.svg)](https://github.com/jmrenouard/MySQLTuner-perl/releases/tag/v2.8.43) +[![Test Status](https://github.com/jmrenouard/MySQLTuner-perl/workflows/Test/badge.svg)](https://github.com/jmrenouard/MySQLTuner-perl/actions) [![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/jmrenouard/MySQLTuner-perl.svg)](https://isitmaintained.com/project/jmrenouard/MySQLTuner-perl "Average time to resolve an issue") [![Percentage of open issues](https://isitmaintained.com/badge/open/jmrenouard/MySQLTuner-perl.svg)](https://isitmaintained.com/project/jmrenouard/MySQLTuner-perl "Percentage of issues still open") [![GPL License](https://badges.frapsoft.com/os/gpl/gpl.png?v=103)](https://opensource.org/licenses/GPL-3.0/) **MySQLTuner** is a script written in Perl that allows you to review a MySQL installation quickly and make adjustments to increase performance and stability. The current configuration variables and status data is retrieved and presented in a brief format along with some basic performance suggestions. -**MySQLTuner** supports ~300 indicators and KPIs (including Weighted Health Score) for MySQL/MariaDB/Percona Server in this latest version. +**MySQLTuner** supports ~900+ indicators, KPIs, and recommendations (including Weighted Health Score, Predictive Capacity Planning, and SSL/TLS Audit) for MySQL/MariaDB/Percona Server in this latest version. **MySQLTuner** is actively maintained supporting many configurations such as [Galera Cluster](https://galeracluster.com/), [TokuDB](https://www.percona.com/software/mysql-database/percona-tokudb), [Performance schema](https://github.com/mysql/mysql-sys), Linux OS metrics, [InnoDB](https://dev.mysql.com/doc/refman/5.7/en/innodb-storage-engine.html), [MyISAM](https://dev.mysql.com/doc/refman/5.7/en/myisam-storage-engine.html), [Aria](https://mariadb.com/docs/server/server-usage/storage-engines/aria/aria-storage-engine), ... @@ -40,7 +40,7 @@ MySQLTuner needs you * Paid support for LightPath here: [jmrenouard@lightpath.fr](jmrenouard@lightpath.fr) * Paid support for Releem available here: [Releem App](https://releem.com/) -![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&theme=radical) +![jmrenouard's GitHub stats](https://github-readme-stats.vercel.app/api?username=jmrenouard&show_icons=true&theme=radical) ## Stargazers over time @@ -73,10 +73,19 @@ Thanks to [endoflife.date](https://endoflife.date/) ***Advanced Intelligence & Ecosystem*** -* **Weighted Health Score KPI**: Overall database health assessment based on performance, security, and resilience. -* **Smart Migration LTS Advisor**: Identification of risks when migrating to modern LTS versions (MySQL 8.4/9.0+, MariaDB 11.x). -* **Predictive Capacity Planning**: Memory headroom analysis and disk growth forecasting. -* **Cloud Discovery**: native support for AWS RDS/Aurora, GCP Cloud SQL, Azure (Flexible/Managed), and DigitalOcean. +* **Weighted Health Score KPI**: Overall database health assessment (0-100) based on Performance (40pts), Security (30pts), and Resilience (30pts). +* **Smart Migration LTS Advisor**: Identification of risks when migrating to modern LTS versions (MySQL 8.4/9.0+, MariaDB 11.x), including removed variables and deprecated authentication methods. +* **Predictive Capacity Planning**: Memory headroom analysis (peak vs available RAM+Swap), disk growth forecasting, and AUTO_INCREMENT capacity near max value detection. +* **Cloud Autodiscovery**: Native support for AWS RDS/Aurora, GCP Cloud SQL, Azure (Flexible/Managed), and DigitalOcean. Automatic detection via `@@version_comment` and provider-specific variables. +* **Infrastructure-Aware Tuning**: Detection of SSD/NVMe vs HDD storage types and ARM64/Graviton vs x86_64 architectures. Adjusts recommendations for `innodb_flush_neighbors` and `innodb_io_capacity`. +* **SSL/TLS Security Audit**: Session encryption check, TLS version audit (warn on TLSv1.0/1.1), certificate expiration, `require_secure_transport` enforcement, and remote user SSL checks. +* **Authentication Plugin Auditing**: Detection of insecure plugins (`mysql_native_password`, `sha256_password`), MySQL 9.x readiness diagnostics, and MariaDB `ed25519`/`unix_socket` recommendations. +* **Schema Modeling & Naming Conventions**: Comprehensive table structure analysis (missing PKs, surrogate key types, UTF-8 compliance, non-InnoDB tables), naming convention audit (snake_case/camelCase consistency, plural detection, boolean/date column prefixes), and foreign key analysis (unconstrained `_id` columns, type mismatches, CASCADE audit). +* **MySQL 8.0+ / MariaDB Modeling**: JSON column indexability (virtual generated columns), invisible indexes, CHECK constraints. +* **Guided Auto-Fix Engine**: Generation of ready-to-apply `SET GLOBAL` SQL statements and `[mysqld]` configuration blocks from the variable adjustment recommendations. +* **Historical Trend Analysis**: Ingest JSON output from previous runs via `--compare-file` to track QPS and data growth trends. +* **Sysbench Integration**: Parse sysbench output for QPS, TPS, and latency metrics (Avg/95th/Max) via `--sysbench-file`. +* **Container & Systemd Log Integration**: Automatic log detection from Docker, Podman, Kubectl/Kubernetes, and Systemd journal. ***Unsupported storage engines: PRs welcome*** -- @@ -156,6 +165,22 @@ What is MySQLTuner checking exactly ? All checks done by **MySQLTuner** are documented in [MySQLTuner Internals](https://github.com/jmrenouard/MySQLTuner-perl/blob/master/INTERNALS.md) documentation. +**MySQLTuner** analyzes the following areas: + +* **System & OS**: RAM, swap, open ports, kernel parameters, load average, mount points, network cards +* **Server Version**: EOL detection, architecture, 64-bit recommendations +* **Error Logs**: Local files, Docker/Podman containers, Kubernetes pods, Systemd journal +* **Cloud & Infrastructure**: AWS RDS/Aurora, GCP, Azure, DigitalOcean; SSD/NVMe vs HDD; ARM64/x86_64 +* **Storage Engines**: InnoDB (buffer pool, redo log, chunk size), MyISAM, Aria, Galera, TokuDB, RocksDB +* **Security**: Anonymous users, weak passwords, SSL/TLS audit, authentication plugins, CVE vulnerabilities +* **Connections**: Usage percentages, aborted connections, thread cache +* **Performance**: Sort/join/temp tables, global buffers, query cache, slow queries, memory usage +* **Replication**: Source/Replica status, lag, GTID, semi-sync, multi-source +* **Performance Schema**: Top users/hosts/statements, IO latency, lock waits, unused indexes, redundant indexes +* **Schema Modeling**: Primary key analysis, naming conventions, foreign keys, data types, UTF-8 compliance, JSON indexability +* **Predictive**: Memory headroom, disk growth forecasting, AUTO_INCREMENT capacity +* **Health Score**: Weighted KPI (0-100) aggregating Performance, Security, and Resilience findings + Download/Installation -- @@ -389,6 +414,65 @@ perl mysqltuner.pl --json --outputfile=run1.json perl mysqltuner.pl --compare-file=run1.json ``` +**Usage:** Export one Markdown file per schema (schema documentation) + +```bash +perl mysqltuner.pl --verbose --schemadir=./schemas +``` + +**Usage:** Dump data with row limits and gzip compression + +```bash +perl mysqltuner.pl --verbose --dumpdir=./result --dump-limit=10000 --compress-dump +``` + +**Usage:** Container mode (analyze a database running in Docker) + +```bash +perl mysqltuner.pl --verbose --container docker:mysql_container_name +``` + +**Usage:** Table structure and naming convention analysis + +```bash +perl mysqltuner.pl --structstat +``` + +**Usage:** Filter output (show only problems) + +```bash +perl mysqltuner.pl --nogood --noinfo +``` + +**Usage:** JSON output (for automation and reporting pipelines) + +```bash +perl mysqltuner.pl --json --outputfile=report.json +perl mysqltuner.pl --prettyjson +``` + +**Usage:** Non-dedicated server mode (shared hosting) + +```bash +perl mysqltuner.pl --nondedicated +``` + +**Usage:** Use credentials from environment variables + +```bash +export MYSQL_USER=mysqltuner +export MYSQL_PASS=secret +perl mysqltuner.pl --userenv=MYSQL_USER --passenv=MYSQL_PASS +``` + +**Usage:** Use a custom defaults file + +```bash +perl mysqltuner.pl --defaults-file=/path/to/my.cnf +``` + +For a complete list of all available options, run `perl mysqltuner.pl --help` or refer to the [USAGE.md](https://github.com/jmrenouard/MySQLTuner-perl/blob/master/USAGE.md) documentation. + Cloud Support -- @@ -640,69 +724,33 @@ perl mysqltuner.pl * **Air-gapped environments:** If your server has no direct internet access, download the files above on a host that has internet access (or via a proxy), then transfer `mysqltuner.pl`, `basic_passwords.txt`, and `vulnerabilities.csv` to the target server using `scp`, `rsync`, or another file transfer method. -MySQLTuner and Vagrant +MySQLTuner and Vagrant (Legacy) -- -**MySQLTuner** contains following Vagrant configurations: - -* Fedora Core 30 / Docker - -**Vagrant File** is stored in Vagrant subdirectory. - -* Follow following step after vagrant installation: - * `$ vagrant up` - -**MySQLTuner** contains a Vagrant configurations for test purpose and development - -* Install VirtualBox and Vagrant - * - * -* Clone repository - * `git clone` -* Install Vagrant plugins vagrant-hostmanager and vagrant-vbguest - * `vagrant plugin install vagrant-hostmanager` - * `vagrant plugin install vagrant-vbguest` -* Add Fedora Core 30 box for official Fedora Download Website - * `vagrant box add --name generic/fedora30` -* Create a data directory - * `mkdir data` - -## setup test environments - - $ sh build/createTestEnvs.sh - - $ source build/bashrc - $ mysql_percona80 sakila - sakila> ... - - $ docker images - mariadb 10.1 fc612450e1f1 12 days ago 352MB - mariadb 10.2 027b7c57b8c6 12 days ago 340MB - mariadb 10.3 47dff68107c4 12 days ago 343MB - mariadb 10.4 92495405fc36 12 days ago 356MB - mysql 5.6 95e0fc47b096 2 weeks ago 257MB - mysql 8.0 b8fd9553f1f0 2 weeks ago 445MB - percona/percona-server 5.7 ddd245ed3496 5 weeks ago 585MB - percona/percona-server 5.6 ed0a36e0cf1b 6 weeks ago 421MB - percona/percona-server 8.0 390ae97d57c6 6 weeks ago 697MB - mariadb 5.5 c7bf316a4325 4 months ago 352MB - mariadb 10.0 d1bde56970c6 4 months ago 353MB - mysql 5.5 d404d78aa797 4 months ago 205MB - - $ docker ps - CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES - da2be9b050c9 mariadb:5.5 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5311->3306/tcp mariadb55 - 5deca25d5ac8 mariadb:10.0 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5310->3306/tcp mariadb100 - 73aaeb37e2c2 mariadb:10.1 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5309->3306/tcp mariadb101 - 72ffa77e01ec mariadb:10.2 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5308->3306/tcp mariadb102 - f5996f2041df mariadb:10.3 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5307->3306/tcp mariadb103 - 4890c52372bb mariadb:10.4 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5306->3306/tcp mariadb104 - 6b9dc078e921 percona/percona-server:5.6 "/docker-entrypoint.…" 7 hours ago Up 7 hours 0.0.0.0:4308->3306/tcp percona56 - 3a4c7c826d4c percona/percona-server:5.7 "/docker-entrypoint.…" 7 hours ago Up 7 hours 0.0.0.0:4307->3306/tcp percona57 - 3dda408c91b0 percona/percona-server:8.0 "/docker-entrypoint.…" 7 hours ago Up 7 hours 33060/tcp, 0.0.0.0:4306->3306/tcp percona80 - 600a4e7e9dcd mysql:5.5 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:3309->3306/tcp mysql55 - 4bbe54342e5d mysql:5.6 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:3308->3306/tcp mysql56 - d985820667c2 mysql:8.0 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:3306->3306/tcp, 33060/tcp mysql 8 0 +> **Note:** The Vagrant-based test environment is considered legacy. For modern testing, use the Docker-based test suite via `make test-it` or `build/test_envs.sh`. + +**Vagrant File** is stored in the Vagrant subdirectory. + +## Setup Docker test environments + +MySQLTuner includes a Docker-based test infrastructure for multi-version validation: + +```bash +# Create and start all test containers +sh build/createTestEnvs.sh + +# Source environment helpers +source build/bashrc + +# Connect to a specific database +mysql_percona80 sakila +``` + +**Supported test targets** (refer to [MariaDB support](mariadb_support.md) and [MySQL support](mysql_support.md) for the current compatibility matrix): + +* MySQL 8.0, 8.4, 9.x +* MariaDB 10.6, 10.11, 11.4, 11.8 +* Percona Server 8.0 Contributions welcome -- diff --git a/README.ru.md b/README.ru.md index 8e5b97777..720e49c96 100644 --- a/README.ru.md +++ b/README.ru.md @@ -3,14 +3,14 @@ [!["Купите нам кофе"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/jmrenouard) [![Статус проекта](https://opensource.box.com/badges/active.svg)](https://opensource.box.com/badges) -[![Статус тестов](https://github.com/anuraghazra/github-readme-stats/workflows/Test/badge.svg)](https://github.com/anuraghazra/github-readme-stats/) +[![Статус тестов](https://github.com/jmrenouard/MySQLTuner-perl/workflows/Test/badge.svg)](https://github.com/jmrenouard/MySQLTuner-perl/actions) [![Среднее время решения проблемы](https://isitmaintained.com/badge/resolution/jmrenouard/MySQLTuner-perl.svg)](https://isitmaintained.com/project/jmrenouard/MySQLTuner-perl "Среднее время решения проблемы") [![Процент открытых проблем](https://isitmaintained.com/badge/open/jmrenouard/MySQLTuner-perl.svg)](https://isitmaintained.com/project/jmrenouard/MySQLTuner-perl "Процент все еще открытых проблем") [![Лицензия GPL](https://badges.frapsoft.com/os/gpl/gpl.png?v=103)](https://opensource.org/licenses/GPL-3.0/) **MySQLTuner** — это скрипт, написанный на Perl, который позволяет быстро просмотреть установку MySQL и внести коррективы для повышения производительности и стабильности. Текущие переменные конфигурации и данные о состоянии извлекаются и представляются в кратком формате вместе с некоторыми основными предложениями по производительности. -**MySQLTuner** поддерживает около 300 индикаторов и KPI (включая средневзвешенный показатель здоровья) для MySQL/MariaDB/Percona Server в этой последней версии. +**MySQLTuner** поддерживает около 900+ индикаторов, KPI и рекомендаций (включая средневзвешенный показатель здоровья, прогнозное планирование мощностей и аудит SSL/TLS) для MySQL/MariaDB/Percona Server в этой последней версии. **MySQLTuner** активно поддерживается и поддерживает множество конфигураций, таких как [кластер Galera](https://galeracluster.com/), [TokuDB](https://www.percona.com/software/mysql-database/percona-tokudb), [схема производительности](https://github.com/mysql/mysql-sys), метрики ОС Linux, [InnoDB](https://dev.mysql.com/doc/refman/5.7/en/innodb-storage-engine.html), [MyISAM](https://dev.mysql.com/doc/refman/5.7/en/myisam-storage-engine.html), [Aria](https://mariadb.com/docs/server/server-usage/storage-engines/aria/aria-storage-engine), ... @@ -38,7 +38,7 @@ MySQLTuner нуждается в вас * Платная поддержка LightPath здесь: [jmrenouard@lightpath.fr](jmrenouard@lightpath.fr) * Платная поддержка Releem доступна здесь: [приложение Releem](https://releem.com/) -![Статистика GitHub Анурага](https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&theme=radical) +![Статистика GitHub jmrenouard](https://github-readme-stats.vercel.app/api?username=jmrenouard&show_icons=true&theme=radical) ## Звездочеты с течением времени @@ -71,10 +71,19 @@ MySQLTuner нуждается в вас ***Расширенная аналитика и экосистема*** -* **KPI средневзвешенного показателя здоровья**: общая оценка состояния базы данных на основе производительности, безопасности и отказоустойчивости. -* **Советник по интеллектуальной миграции LTS**: выявление рисков при миграции на современные версии LTS (MySQL 8.4/9.0+, MariaDB 11.x). -* **Прогнозное планирование мощностей**: анализ запаса памяти и прогнозирование роста дискового пространства. -* **Облачное обнаружение**: нативная поддержка AWS RDS/Aurora, GCP Cloud SQL, Azure (Flexible/Managed) и DigitalOcean. +* **KPI средневзвешенного показателя здоровья**: общая оценка состояния базы данных (0-100) на основе производительности (40очков), безопасности (30очков) и отказоустойчивости (30очков). +* **Советник по интеллектуальной миграции LTS**: выявление рисков при миграции на современные версии LTS (MySQL 8.4/9.0+, MariaDB 11.x), включая удалённые переменные и устаревшие методы аутентификации. +* **Прогнозное планирование мощностей**: анализ запаса памяти (пик vs доступная RAM+Swap), прогнозирование роста дискового пространства, обнаружение ёмкости AUTO_INCREMENT близкой к максимуму. +* **Автообнаружение облака**: нативная поддержка AWS RDS/Aurora, GCP Cloud SQL, Azure (Flexible/Managed) и DigitalOcean. Автоматическое обнаружение через `@@version_comment` и переменные, специфичные для провайдера. +* **Адаптивная настройка под инфраструктуру**: обнаружение типов хранилищ SSD/NVMe vs HDD и архитектур ARM64/Graviton vs x86_64. Корректировка рекомендаций для `innodb_flush_neighbors` и `innodb_io_capacity`. +* **Аудит безопасности SSL/TLS**: проверка шифрования сессии, аудит версий TLS (предупреждение о TLSv1.0/1.1), срок действия сертификатов, применение `require_secure_transport`, проверка SSL для удалённых пользователей. +* **Аудит плагинов аутентификации**: обнаружение небезопасных плагинов (`mysql_native_password`, `sha256_password`), диагностика совместимости MySQL 9.x, рекомендации MariaDB `ed25519`/`unix_socket`. +* **Моделирование схемы и конвенции именования**: полный анализ структуры таблиц (отсутствие PK, типы суррогатных ключей, соответствие UTF-8, таблицы не-InnoDB), аудит конвенций именования (snake_case/camelCase, обнаружение множественного числа, префиксы булевых столбцов/дат) и анализ внешних ключей (столбцы `_id` без ограничений, несоответствия типов, аудит CASCADE). +* **Моделирование MySQL 8.0+ / MariaDB**: индексируемость столбцов JSON (генерируемые виртуальные столбцы), невидимые индексы, ограничения CHECK. +* **Движок Auto-Fix с управляемым исправлением**: генерация SQL-инструкций `SET GLOBAL` и блоков конфигурации `[mysqld]` из рекомендаций по настройке переменных. +* **Анализ исторических тенденций**: поглощение JSON-вывода предыдущих запусков через `--compare-file` для отслеживания тенденций QPS и роста данных. +* **Интеграция Sysbench**: анализ вывода sysbench для метрик QPS, TPS и латентности (Средн./95-й/Макс) через `--sysbench-file`. +* **Интеграция логов Container и Systemd**: автоматическое обнаружение логов из Docker, Podman, Kubectl/Kubernetes и журнала Systemd. ***Неподдерживаемые механизмы хранения: приветствуются PR*** -- @@ -154,6 +163,22 @@ GRANT SELECT, PROCESS, EXECUTE, REPLICATION CLIENT, SHOW DATABASES, SHOW VIEW ON Все проверки, выполняемые **MySQLTuner**, задокументированы в документации [MySQLTuner Internals](https://github.com/jmrenouard/MySQLTuner-perl/blob/master/INTERNALS.md). +**MySQLTuner** анализирует следующие области: + +* **Система и ОС**: RAM, swap, открытые порты, параметры ядра, нагрузка, точки монтирования, сетевые интерфейсы +* **Версия сервера**: обнаружение EOL, архитектура, рекомендации 64-битной версии +* **Логи ошибок**: локальные файлы, контейнеры Docker/Podman, поды Kubernetes, журнал Systemd +* **Облако и инфраструктура**: AWS RDS/Aurora, GCP, Azure, DigitalOcean; SSD/NVMe vs HDD; ARM64/x86_64 +* **Движки хранения**: InnoDB (buffer pool, redo log, chunk size), MyISAM, Aria, Galera, TokuDB, RocksDB +* **Безопасность**: анонимные пользователи, слабые пароли, аудит SSL/TLS, плагины аутентификации, уязвимости CVE +* **Соединения**: проценты использования, прерванные соединения, кэш потоков +* **Производительность**: сортировка/объединения/временные таблицы, глобальные буферы, кэш запросов, медленные запросы, использование памяти +* **Репликация**: состояние Source/Replica, отставание, GTID, semi-sync, multi-source +* **Performance Schema**: топ пользователей/хостов/запросов, латентность IO, ожидание блокировок, неиспользуемые индексы, избыточные индексы +* **Моделирование схемы**: анализ первичных ключей, конвенции именования, внешние ключи, типы данных, соответствие UTF-8, индексируемость JSON +* **Прогнозирование**: запас памяти, прогноз роста диска, ёмкость AUTO_INCREMENT +* **Показатель здоровья**: взвешенный KPI (0-100), агрегирующий результаты производительности, безопасности и отказоустойчивости + Скачивание/установка -- @@ -373,6 +398,65 @@ perl mysqltuner.pl --debug perl mysqltuner.pl --checkversion --updateversion ``` +**Использование:** интеграция результатов производительности Sysbench + +```bash +perl mysqltuner.pl --sysbench-file=/путь/к/вывод_sysbench.txt +``` + +**Использование:** анализ исторических тенденций (сравнение с предыдущим запуском) + +```bash +perl mysqltuner.pl --json --outputfile=run1.json +# ... некоторое время спустя ... +perl mysqltuner.pl --compare-file=run1.json +``` + +**Использование:** экспорт Markdown-файла по схеме (документация схемы) + +```bash +perl mysqltuner.pl --verbose --schemadir=./schemas +``` + +**Использование:** экспорт данных с ограничением строк и сжатием gzip + +```bash +perl mysqltuner.pl --verbose --dumpdir=./result --dump-limit=10000 --compress-dump +``` + +**Использование:** режим контейнера (анализ базы данных в Docker) + +```bash +perl mysqltuner.pl --verbose --container docker:имя_контейнера_mysql +``` + +**Использование:** анализ структуры таблиц и конвенций именования + +```bash +perl mysqltuner.pl --structstat +``` + +**Использование:** фильтрация вывода (показывать только проблемы) + +```bash +perl mysqltuner.pl --nogood --noinfo +``` + +**Использование:** вывод JSON (для автоматизации и конвейеров отчётности) + +```bash +perl mysqltuner.pl --json --outputfile=report.json +perl mysqltuner.pl --prettyjson +``` + +**Использование:** режим невыделенного сервера (общий хостинг) + +```bash +perl mysqltuner.pl --nondedicated +``` + +Для полного списка всех доступных опций выполните `perl mysqltuner.pl --help` или обратитесь к документации [USAGE.md](https://github.com/jmrenouard/MySQLTuner-perl/blob/master/USAGE.md). + Поддержка облака -- @@ -614,71 +698,33 @@ perl mysqltuner.pl * **Изолированные среды (air-gapped):** Если у вашего сервера нет прямого доступа к Интернету, загрузите файлы на хост с доступом к Интернету (или через прокси-сервер), а затем передайте `mysqltuner.pl`, `basic_passwords.txt` и `vulnerabilities.csv` на целевой сервер с помощью `scp`, `rsync` или другого метода передачи файлов. -MySQLTuner и Vagrant +MySQLTuner и Vagrant (устаревшее) -- -**MySQLTuner** содержит следующие конфигурации Vagrant: - -* Fedora Core 30 / Docker +> **Примечание:** Тестовая среда на базе Vagrant считается устаревшей. Для современного тестирования используйте набор тестов на базе Docker через `make test-it` или `build/test_envs.sh`. **Файл Vagrant** хранится в подкаталоге Vagrant. -* Выполните следующие действия после установки Vagrant: - $ vagrant up - -**MySQLTuner** содержит конфигурации Vagrant для целей тестирования и разработки - -* Установите VirtualBox и Vagrant - * - * -* Клонируйте репозиторий - * git clone -* Установите плагины Vagrant vagrant-hostmanager и vagrant-vbguest - * vagrant plugin install vagrant-hostmanager - * vagrant plugin install vagrant-vbguest -* Добавьте образ Fedora Core 30 с официального сайта загрузки Fedora - * vagrant box add --name generic/fedora30 -* Создайте каталог данных - * mkdir data - -## настроить тестовые среды - - $ sh build/createTestEnvs.sh - - $ source build/bashrc - $ mysql_percona80 sakila - sakila> ... - - $ docker images - mariadb 10.1 fc612450e1f1 12 days ago 352MB - mariadb 10.2 027b7c57b8c6 12 days ago 340MB - mariadb 10.3 47dff68107c4 12 days ago 343MB - mariadb 10.4 92495405fc36 12 days ago 356MB - mysql 5.6 95e0fc47b096 2 weeks ago 257MB - mysql 5.7 383867b75fd2 2 weeks ago 373MB - mysql 8.0 b8fd9553f1f0 2 weeks ago 445MB - percona/percona-server 5.7 ddd245ed3496 5 weeks ago 585MB - percona/percona-server 5.6 ed0a36e0cf1b 6 weeks ago 421MB - percona/percona-server 8.0 390ae97d57c6 6 weeks ago 697MB - mariadb 5.5 c7bf316a4325 4 months ago 352MB - mariadb 10.0 d1bde56970c6 4 months ago 353MB - mysql 5.5 d404d78aa797 4 months ago 205MB - - $ docker ps - CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES - da2be9b050c9 mariadb:5.5 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5311->3306/tcp mariadb55 - 5deca25d5ac8 mariadb:10.0 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5310->3306/tcp mariadb100 - 73aaeb37e2c2 mariadb:10.1 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5309->3306/tcp mariadb101 - 72ffa77e01ec mariadb:10.2 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5308->3306/tcp mariadb102 - f5996f2041df mariadb:10.3 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5307->3306/tcp mariadb103 - 4890c52372bb mariadb:10.4 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:5306->3306/tcp mariadb104 - 6b9dc078e921 percona/percona-server:5.6 "/docker-entrypoint.…" 7 hours ago Up 7 hours 0.0.0.0:4308->3306/tcp percona56 - 3a4c7c826d4c percona/percona-server:5.7 "/docker-entrypoint.…" 7 hours ago Up 7 hours 0.0.0.0:4307->3306/tcp percona57 - 3dda408c91b0 percona/percona-server:8.0 "/docker-entrypoint.…" 7 hours ago Up 7 hours 33060/tcp, 0.0.0.0:4306->3306/tcp percona80 - 600a4e7e9dcd mysql:5.5 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:3309->3306/tcp mysql55 - 4bbe54342e5d mysql:5.6 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:3308->3306/tcp mysql56 - a49783249a11 mysql:5.7 "docker-entrypoint.s…" 7 hours ago Up 7 hours 33060/tcp, 0.0.0.0:3307->3306/tcp mysql57 - d985820667c2 mysql:8.0 "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:3306->3306/tcp, 33060/tcp mysql 8 0 +## Настройка тестовых сред Docker + +MySQLTuner включает инфраструктуру тестирования на базе Docker для мульти-версионной валидации: + +```bash +# Создать и запустить все тестовые контейнеры +sh build/createTestEnvs.sh + +# Загрузить хелперы окружения +source build/bashrc + +# Подключиться к конкретной базе данных +mysql_percona80 sakila +``` + +**Поддерживаемые цели тестирования** (см. [поддержка MariaDB](mariadb_support.md) и [поддержка MySQL](mysql_support.md) для текущей матрицы совместимости): + +* MySQL 8.0, 8.4, 9.x +* MariaDB 10.6, 10.11, 11.4, 11.8 +* Percona Server 8.0 Приветствуются вклады -- diff --git a/ROADMAP.md b/ROADMAP.md index 28dd87f92..34f8d6836 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -7,8 +7,8 @@ This document outlines the strategic direction and future development plans for To ensure consistency and high-density development, the following roles are defined for roadmap orchestration: * **Owner**: [Jean-Marie Renouard](https://github.com/jmrenouard) (@jmrenouard) - Ultimate authority on the project, constitution, and core mission. -* **Product Manager**: **Antigravity (AI Agent)** - Responsible for backlog management, specification design, and execution tracking of the roadmap items. * **Release Manager**: **Antigravity (AI Agent)** - Responsible for technical validation, testing orchestration, and unified release cycle execution. +* **Product Manager**: **Antigravity (AI Agent)** - Responsible for backlog management, specification design, and execution tracking of the roadmap items. ## 🌟 Strategic Pillars @@ -47,10 +47,8 @@ To ensure consistency and high-density development, the following roles are defi * [x] **Sysbench Metrics Integration**: Automated baseline capture and performance comparison within the report. * [x] **Multi-Cloud Autodiscovery**: Automated detection of RDS, GCP, and Azure specific performance flags and optimizations. * [x] **Query Anti-Pattern Detection**: Use `performance_schema` to identify non-SARGable queries and `SELECT *` abuse. -* [/] **Modular Reporting Engine**: (In Progress) Refactor Jinja2 templates for dynamic section injection. -* [/] **Historical Trend Analysis**: (Experimental) Allow the script to ingest previous run data to identify performance regressions. -### [Phase 4: Advanced Intelligence & Ecosystem](file:///documentation/specifications/roadmap_phase_iv_intelligence.md) +### [Phase 4: Advanced Intelligence & Ecosystem](file:///documentation/specifications/roadmap_phase_iv_intelligence.md) [IN PROGRESS] * [/] **Smart Migration LTS Advisor**: * [x] Automated pre-upgrade risk reports (variable removal, deprecation notices). @@ -64,24 +62,50 @@ To ensure consistency and high-density development, the following roles are defi * [x] AUTO_INCREMENT capacity near max value detection. * [x] **Cluster & Replication Intelligence**: * [x] Root cause analysis for replication lag (IO/SQL thread contention). - * [ ] GTID consistency checks and multi-source replication tuning. + * [x] GTID consistency checks and multi-source replication tuning. * [x] **Consolidated SQL Modeling & Naming Conventions**: * [x] Consolidated Primary Key naming, surrogate keys, table singular naming, and table/column casing checks into single-line counters in General recommendations. * [x] Implemented advanced dominant style detection and deviations audit for tables, views, indexes, and columns. -* [ ] **CSV Export Enhancements**: - * [ ] Export naming convention deviations (tables, views, indexes, columns), primary key naming/surrogate key issues, missing foreign keys, JSON columns without virtual columns, and insecure authentication plugins to separate CSV files. +* [x] **CSV Export Enhancements**: + * [x] Export naming convention deviations (tables, views, indexes, columns), primary key naming/surrogate key issues, missing foreign keys, JSON columns without virtual columns, and insecure authentication plugins to separate CSV files. * [/] **Security Hardening 2.0**: * [ ] Version-based CVE exposure detection (community-fed database). * [x] Advanced encryption-at-rest (TDE) and SSL/TLS cipher suite validation. - * [ ] **Extended Authentication Plugins Audit**: Verify password hashing methods against the extended plugins support matrix (including `mysql_native_password`, `mysql_old_password`, `sha256_password`, `caching_sha2_password`, `unix_socket`, `ed25519`, and the new MariaDB `parsec` plugin). See [AUTHENTICATION_PLUGINS.md](file:///documentation/AUTHENTICATION_PLUGINS.md). + * [x] **Extended Authentication Plugins Audit**: Verify password hashing methods against the extended plugins support matrix (including `mysql_native_password`, `mysql_old_password`, `sha256_password`, `caching_sha2_password`, `unix_socket`, `ed25519`, and the new MariaDB `parsec` plugin). See [AUTHENTICATION_PLUGINS.md](file:///documentation/AUTHENTICATION_PLUGINS.md). * [/] **Guided Auto-Fix Engine**: * [ ] Interactive mode to simulate configuration changes. * [x] Generation of ready-to-use `SET GLOBAL` or `my.cnf` snippets. +* [/] **Modular Reporting Engine**: (In Progress) Refactor Jinja2 templates for dynamic section injection. +* [/] **Historical Trend Analysis**: (Experimental) Allow the script to ingest previous run data to identify performance regressions. + +--- + +### Phase 5: Code Quality & Regression Hardening [NEW — PRIORITY] + +> Derived from the test campaign analysis on v2.8.43. Addresses critical code quality issues identified during the 5-iteration test audit. + +* [ ] **Perl Warning Elimination**: + * [ ] Add definedness guards to `mysql_version_ge()`, `mysql_version_le()`, `mysql_version_eq()` to prevent 74 uninitialized value warnings. + * [ ] Guard `$mycalc{'innodb_log_size_pct'}` and `$myvar{'innodb_log_file_size'}` before use in InnoDB analysis. + * [ ] Guard `$myvar{'version_comment'}` in MariaDB detection path. +* [ ] **Version Validation Updates**: + * [ ] Add MySQL 9.6 to `validate_mysql_version()` supported LTS list. + * [ ] Remove MySQL 9.5 (now Outdated) from the LTS list. +* [ ] **Test Coverage Expansion**: + * [ ] Achieve ≥80% subroutine test coverage (currently ~55%, 74 of 165 uncovered). + * [ ] Priority coverage: `check_architecture`, `system_recommendations`, `mysql_indexes`, `mysql_views`, `mysql_routines`, `mysql_triggers`, `make_recommendations`. + * [ ] Add tests for `dump_result`, `close_outputfile`, `get_template_model`. +* [ ] **Version Comparison Optimization**: + * [ ] Cache parsed version components instead of re-parsing `$myvar{'version'}` on every call to `mysql_version_ge/le/eq`. -### Phase 5: Deep Engine Tuning & Safeguarding [([Specification](file:///documentation/specifications/roadmap_phase_v_innodb.md))] +--- + +### [Phase 6: Deep Engine Tuning & Safeguarding](file:///documentation/specifications/roadmap_phase_v_innodb.md) [NOT STARTED] + +> Previously Phase 5. Renumbered for logical sequencing after inserting Code Quality phase. * [ ] **InnoDB Internals 3.0**: - * [/] **I/O Pressure & Flushing Advisor**: Combined analysis of `innodb_io_capacity`, `Innodb_buffer_pool_wait_free`, and adaptive flushing metrics to prevent I/O stalls. + * [ ] **I/O Pressure & Flushing Advisor**: Combined analysis of `innodb_io_capacity`, `Innodb_buffer_pool_wait_free`, and adaptive flushing metrics to prevent I/O stalls. *(Basic SSD check exists, full advisory missing)* * [ ] **Read-Ahead Efficiency Audit**: Measure `Innodb_buffer_pool_read_ahead_evicted` vs `Innodb_buffer_pool_read_ahead` to optimize `innodb_read_ahead_threshold`. * [ ] **Deadlock & Contention Analytics**: Historic deadlock tracking via `performance_schema` with specific table-level contention reports. * [ ] **Modern Storage Alignment**: Deep audit of `innodb_doublewrite_pages` alignment (128 for MySQL 8.4+), `innodb_use_fdatasync` for syscall reduction, and `innodb_flush_method`. @@ -92,7 +116,9 @@ To ensure consistency and high-density development, the following roles are defi * [ ] **Read-Ahead & Change Buffer Optimization**: Dynamic recommendation to disable legacy features (`innodb_change_buffering`, `innodb_adaptive_hash_index`) based on workload patterns. * [ ] **Purge Lag Prevention**: Automated detected of purge lag (`Innodb_history_list_length`) and recommendation for `innodb_purge_threads` scaling. -### [Phase 6: High Availability & InnoDB Cluster](file:///documentation/specifications/roadmap_phase_vi_innodb_cluster.md) +### [Phase 7: High Availability & InnoDB Cluster](file:///documentation/specifications/roadmap_phase_vi_innodb_cluster.md) [NOT STARTED] + +> Previously Phase 6. No code implementation exists yet. * [ ] **Distributed Consistency & Performance**: * [ ] **Group Replication Health Audit**: Detailed analysis of `MEMBER_STATE`, `MEMBER_ROLE`, and `MEMBER_VERSION` via `performance_schema.replication_group_members`. @@ -107,10 +133,12 @@ To ensure consistency and high-density development, the following roles are defi * [ ] **Quorum Integrity Framework**: Alignment check for `unreachable_majority_timeout` and partition handling configurations. * [ ] **MTR (Multi-Threaded Replication) Scaling**: Dynamic advisory for `slave_parallel_workers` based on cluster apply lag. -### [Phase 7: Modern Replication & GTID Mastery](file:///documentation/specifications/roadmap_phase_vii_replication.md) +### [Phase 8: Modern Replication & GTID Mastery](file:///documentation/specifications/roadmap_phase_vii_replication.md) [PARTIAL] + +> Previously Phase 7. Basic GTID checks exist (7 references). Parallel/compression/semi-sync are missing. -* [ ] **Data Consistency & GTID Integrity**: - * [ ] **GTID Gap Analysis**: Detection of non-contiguous global transaction identifiers and missing transactions across the replication chain. +* [/] **Data Consistency & GTID Integrity**: + * [/] **GTID Gap Analysis**: Detection of non-contiguous global transaction identifiers and missing transactions across the replication chain. *(Basic GTID mode checks exist)* * [ ] **Consistency Enforcement Audit**: Verification of `enforce_gtid_consistency`, `gtid_mode=ON`, and `binlog_format=ROW` for all nodes. * [ ] **Throughput & Parallelism Optimization**: * [ ] **Parallel Applier (MTR) Tuning**: Advanced monitoring of worker thread saturation and busy-wait distribution. @@ -121,7 +149,9 @@ To ensure consistency and high-density development, the following roles are defi * [ ] **Semi-Sync Safety Check**: Dynamic analysis of semi-synchronous wait points (`AFTER_SYNC` vs `AFTER_COMMIT`) and fallback triggers. * [ ] **Multi-Source Channel Monitoring**: Full observability for multi-master and multi-channel replication topologies. -### [Phase 8: Advanced Galera Cluster 4 & PXC 8.0](file:///documentation/specifications/roadmap_phase_viii_galera.md) +### [Phase 9: Advanced Galera Cluster 4 & PXC 8.0](file:///documentation/specifications/roadmap_phase_viii_galera.md) [PARTIAL] + +> Previously Phase 8. Foundation exists (106 wsrep + 51 galera references). Advanced diagnostics missing. * [ ] **Synchronous Efficiency & Streaming**: * [ ] **Streaming Replication Audit**: Observability for large transaction fragments (`wsrep_streaming_log_writes`) and their I/O footprint (MariaDB 10.4+). @@ -134,10 +164,12 @@ To ensure consistency and high-density development, the following roles are defi * [ ] **Network Jitter Detection**: Monitoring of group communication latency (`wsrep_evs_repl_latency` statistics) and its impact on consistency. * [ ] **PXC Strict Mode Verification**: Consistency checks for Percona XtraDB Cluster specific security and performance enforcements. -### [Phase 9: Data Integrity & Checksum Verification](file:///documentation/specifications/roadmap_phase_ix_integrity.md) +### [Phase 10: Data Integrity & Checksum Verification](file:///documentation/specifications/roadmap_phase_ix_integrity.md) [PARTIAL] -* [ ] **Storage Engine Protection**: - * [/] **InnoDB Page Integrity Audit**: Verification of `innodb_checksum_algorithm` strength (`full_crc32` for MariaDB 10.5+, `CRC32` for MySQL) and ensuring `innodb_checksums` is active. +> Previously Phase 9. Basic checksum algorithm checks exist (5 refs each). Binlog/doublewrite missing. + +* [/] **Storage Engine Protection**: + * [/] **InnoDB Page Integrity Audit**: Verification of `innodb_checksum_algorithm` strength (`full_crc32` for MariaDB 10.5+, `CRC32` for MySQL) and ensuring `innodb_checksums` is active. *(Basic implementation exists)* * [ ] **Redo Log Safety Check**: Monitoring of `innodb_log_checksums` to prevent undetected recovery from corrupted logs. * [ ] **Doublewrite Consistency**: Alignment check between doublewrite buffer activity and storage atomic write capabilities. * [ ] **Replication Pipeline Validation**: @@ -145,16 +177,20 @@ To ensure consistency and high-density development, the following roles are defi * [ ] **End-to-End Verification Audit**: Analysis of `source_verify_checksum` and `replica_sql_verify_checksum` settings. * [ ] **Relay Log Hardening**: Verification of checksum validation before transaction application on replicas. -### Phase 10: Workload Analysis & Traffic Profiling +### Phase 11: Workload Analysis & Traffic Profiling [NOT STARTED] + +> Previously Phase 10. * [ ] **Query Performance Profiling**: -* [ ] **Wait Event Fingerprinting**: Aggregation of `performance_schema` wait events to identify the primary database bottleneck (CPU, disk, lock, network). -* [ ] **Workload Characterization**: Automated classification of the database as Read-Heavy, Write-Heavy, or Mixed based on I/O ratios. + * [ ] **Wait Event Fingerprinting**: Aggregation of `performance_schema` wait events to identify the primary database bottleneck (CPU, disk, lock, network). + * [ ] **Workload Characterization**: Automated classification of the database as Read-Heavy, Write-Heavy, or Mixed based on I/O ratios. * [ ] **Metadata & Object Lifecycle**: -* [ ] **Table Churn & Fragmentation Advisor**: Identification of tables with frequent DML that require periodic `OPTIMIZE TABLE`. -* [ ] **Auto-Increment Exhaustion Audit**: Monitoring of large tables for potential auto-increment overflow (especially 32-bit integers). + * [ ] **Table Churn & Fragmentation Advisor**: Identification of tables with frequent DML that require periodic `OPTIMIZE TABLE`. + * [ ] **Auto-Increment Exhaustion Audit**: Monitoring of large tables for potential auto-increment overflow (especially 32-bit integers). + +### [Phase 12: Advanced Log Parser & Lock Monitoring](file:///documentation/specifications/roadmap_phase_xi_log_parser.md) [NOT STARTED] -### [Phase 11: Advanced Log Parser & Lock Monitoring](file:///documentation/specifications/roadmap_phase_xi_log_parser.md) +> Previously Phase 11. * [ ] **Logging & Lock Instrumentation**: * [ ] **Deadlock Logging Audit**: Verification of `innodb_print_all_deadlocks` and `innodb_status_output` settings. @@ -167,7 +203,9 @@ To ensure consistency and high-density development, the following roles are defi * [ ] **Correlation Engine (Experimental)**: * [ ] **Temporal Event Linking**: Logic to link error log timestamps with Performance Schema wait events or high CPU load detected during execution. -### [Phase 12: Sectional Global Indicators & KPIs](file:///documentation/specifications/roadmap_phase_xii_sectional_indicators.md) +### [Phase 13: Sectional Global Indicators & KPIs](file:///documentation/specifications/roadmap_phase_xii_sectional_indicators.md) [NOT STARTED] + +> Previously Phase 12. * [ ] **Unified Health Dashboard**: * [ ] **Sectional Health Scoring**: Implementation of a 0-100 KPI for each major diagnostic area (Storage Engine, Security, Replication, SQL Modeling). @@ -178,16 +216,18 @@ To ensure consistency and high-density development, the following roles are defi * [ ] **Comparative Insights**: * [ ] **Historical Performance Deltas**: Sectional trend analysis identifying areas of performance regression or improvement based on previous run data. -### [Phase 13: Export Optimization & Dumpdir Hardening](file:///documentation/specifications/roadmap_phase_xiii_export_optimization.md) +### [Phase 14: Export Optimization & Dumpdir Hardening](file:///documentation/specifications/roadmap_phase_xiii_export_optimization.md) [COMPLETED] + +> Previously Phase 13. -* [ ] **Export Performance Safeguards**: - * [ ] **Default Row Limit**: Implementation of a 50,000 rows default limit for all `dumpdir` exports to prevent database slowdowns. - * [ ] **Configurable Quotas**: Addition of `--dump-limit` option to allow user-defined row overrides. -* [ ] **Metadata & Durability**: - * [ ] **Manifest Generation**: Automated generation of `manifest.json`/`metadata.txt` for better traceability of offline diagnostic snapshots. - * [ ] **I/O Latency Monitoring**: Real-time tracking of export duration per object with notices for slow disk subsystems. -* [ ] **Compression & Efficiency**: - * [ ] **On-the-fly Compression**: Support for compressed `.gz` exports to minimize disk footprint in container/limited-storage environments. +* [x] **Export Performance Safeguards**: + * [x] **Default Row Limit**: Implementation of a 50,000 rows default limit for all `dumpdir` exports to prevent database slowdowns. + * [x] **Configurable Quotas**: Addition of `--dump-limit` option to allow user-defined row overrides. +* [x] **Metadata & Durability**: + * [x] **Manifest Generation**: Automated generation of `manifest.json`/`metadata.txt` for better traceability of offline diagnostic snapshots. + * [x] **I/O Latency Monitoring**: Real-time tracking of export duration per object with notices for slow disk subsystems. +* [x] **Compression & Efficiency**: + * [x] **On-the-fly Compression**: Support for compressed `.gz` exports to minimize disk footprint in container/limited-storage environments. ## 🔮 Strategic Technical Evolutions diff --git a/SECURITY.md b/SECURITY.md index 784ec699e..0ad681cb0 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -8,7 +8,7 @@ We provide security updates for the following versions of MySQLTuner: | Version | Status | | ------- | --------------------- | -| v2.x | Supported (v2.8.38) | +| v2.x | Supported (v2.8.43) | | < v2.x | End of Life | We strongly recommend that all users stay updated with the latest stable release available on [GitHub Releases](https://github.com/jmrenouard/MySQLTuner-perl/releases). diff --git a/TESTS.md b/TESTS.md index 41472c7b7..7a117a55d 100644 --- a/TESTS.md +++ b/TESTS.md @@ -7,7 +7,7 @@ The project uses `Test::More` for unit testing. All tests are located in the `te ```bash make unit-tests # OR -prove -r tests/ +perl build/audit_tests.pl ``` ## Laboratory Tests (Docker) diff --git a/USAGE.md b/USAGE.md index d6ad20062..0fa8a3ea7 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1,111 +1,242 @@ -# NAME +# MySQLTuner 2.8.43 — Complete CLI Reference + +MySQLTuner is a MySQL High Performance Tuning Script. + +## Quick Start + +```bash +# Local analysis (simplest) +perl mysqltuner.pl + +# Full verbose output +perl mysqltuner.pl --verbose + +# Remote host analysis +perl mysqltuner.pl --host targetDNS_IP --user admin_user --pass admin_password --forcemem 16G +``` + +## Important Usage Guidelines + +- Allow MySQL server to run for at least **24-48 hours** before trusting suggestions. +- Some routines may require root level privileges (the script will provide warnings). +- You **must** provide the remote server's total memory when connecting to remote hosts without SSH. + +--- + +## CONNECTION AND AUTHENTICATION + +| Option | Description | +|:---|:---| +| `--host ` | Connect to a remote host to perform tests | +| `--port ` | Port to use for connection (default: 3306) | +| `--socket ` | Use a different socket for a local connection | +| `--user ` (`-u`) | Username to use for authentication | +| `--pass ` (`-p`, `--password`) | Password to use for authentication | +| `--userenv ` | Environment variable name for username | +| `--passenv ` | Environment variable name for password | +| `--defaults-file ` | Path to a custom `.my.cnf` | +| `--defaults-extra-file ` | Path to an extra custom config file | +| `--login-path ` | Read options from the specified login path (uses `mysql_config_editor`) | +| `--protocol tcp` | Force TCP connection instead of socket | +| `--ssl-ca ` | Path to public key (SSL CA) | +| `--mysqlcmd ` | Path to a custom `mysql` executable | +| `--mysqladmin ` | Path to a custom `mysqladmin` executable | +| `--pipe` / `--no-pipe` | Connect to a local Windows database using named pipes | +| `--pipe_name ` | Use a different pipe name for a local connection | +| `--server-log ` | Path to an explicit log file (error_log) | + +### Examples + +```bash +# Using a defaults file +perl mysqltuner.pl --defaults-file=/etc/mysql/my.cnf + +# Using environment variables for credentials +export DB_USER=mysqltuner +export DB_PASS=secret +perl mysqltuner.pl --userenv=DB_USER --passenv=DB_PASS + +# Force TCP protocol +perl mysqltuner.pl --host 10.0.0.5 --protocol tcp +``` + +--- + +## CLOUD SUPPORT + +| Option | Description | +|:---|:---| +| `--cloud` / `--no-cloud` | Enable cloud mode | +| `--azure` / `--no-azure` | Enable Azure-specific support | +| `--container ` | Enable container mode with ID or name (e.g., `docker:mysql_container`) | +| `--ssh-host ` | The SSH host for cloud connections | +| `--ssh-user ` | The SSH user for cloud connections | +| `--ssh-password ` | The SSH password for cloud connections (uses `sshpass`) | +| `--ssh-identity-file ` | The path to the SSH identity file | + +### Examples + +```bash +# Analyze a database running in Docker +perl mysqltuner.pl --verbose --container docker:mysql_prod + +# Cloud mode via SSH +perl mysqltuner.pl --cloud --ssh-host db.example.com --ssh-user admin --ssh-identity-file ~/.ssh/id_rsa + +# Azure-specific analysis +perl mysqltuner.pl --azure --host mydb.mysql.database.azure.com --user admin@mydb --pass secret +``` + +--- + +## PERFORMANCE AND REPORTING OPTIONS + +| Option | Description | +|:---|:---| +| `--forcemem ` | Amount of RAM installed (e.g., `10G`, `1024M`, `128K`) | +| `--forceswap ` | Amount of swap memory configured (e.g., `10G`, `1024M`) | +| `--skipsize` / `--no-skipsize` | Don't enumerate tables and their sizes (recommended for large servers) | +| `--buffers` / `--no-buffers` | Print global and per-thread buffer values | +| `--checkversion` / `--no-checkversion` | Check for updates to MySQLTuner | +| `--updateversion` / `--no-updateversion` | Update MySQLTuner if a newer version is available (implies `--checkversion`) | +| `--cvefile ` | CVE file for vulnerability checks (auto-detects `./vulnerabilities.csv`) | +| `--passwordfile ` | Path to a custom password file list (default: `basic_passwords.txt`) | +| `--skippassword` / `--no-skippassword` | Don't perform checks on user passwords | +| `--sysbench-file ` | Path to a sysbench output file for performance metadata integration | +| `--compare-file ` | Path to a previous JSON result file for trend analysis | +| `--feature ` | Run a specific feature/subroutine only (implies `--verbose`) | + +### Output Formats + +| Option | Description | +|:---|:---| +| `--json` / `--no-json` | Print result as JSON string | +| `--prettyjson` / `--no-prettyjson` | Print result as formatted JSON string | +| `--outputfile ` | Path to an output text file | +| `--reportfile ` | Path to a report text file (requires `Text::Template` module) | +| `--template ` | Path to a template file for report generation | + +### Data Export + +| Option | Description | +|:---|:---| +| `--dumpdir ` | Path to a directory where to dump information files (CSV) | +| `--schemadir ` | Path to a directory where to dump one Markdown file per schema | +| `--dump-limit ` | Limit number of rows for dumpdir CSV exports (default: 50000) | +| `--compress-dump` / `--no-compress-dump` | Compress dumped CSV files using gzip | + +### Examples + +```bash +# Full verbose with CVE checks +perl mysqltuner.pl --verbose --cvefile=vulnerabilities.csv + +# JSON output for automation +perl mysqltuner.pl --json --outputfile=report.json + +# Dump all schema data with compression +perl mysqltuner.pl --verbose --dumpdir=./dumps --compress-dump --dump-limit=10000 + +# Export schema documentation as Markdown +perl mysqltuner.pl --verbose --schemadir=./schemas + +# Historical trend analysis +perl mysqltuner.pl --json --outputfile=run1.json +# ... some time later ... +perl mysqltuner.pl --compare-file=run1.json + +# Sysbench integration +perl mysqltuner.pl --sysbench-file=/path/to/sysbench_output.txt +``` + +--- + +## OUTPUT OPTIONS + +| Option | Description | +|:---|:---| +| `--verbose` (`-v`) / `--no-verbose` | Print all options (enables all stat flags below) | +| `--silent` / `--no-silent` | Don't output anything on screen | +| `--color` / `--no-color` | Print output in color (auto-detected for TTY) | +| `--noprettyicon` / `--no-noprettyicon` | Print output with legacy `[OK]`/`[!!]` tags instead of Unicode icons | +| `--debug` / `--no-debug` | Print debug information | +| `--dbgpattern ` | Filter debug output by regex pattern | +| `--experimental` / `--no-experimental` | Print experimental analysis | +| `--nondedicated` / `--no-nondedicated` | Consider server is not dedicated to DB (adjusts memory recommendations) | +| `--noprocess` / `--no-noprocess` | Consider no other process is running | + +### Stat Flags + +These flags control which sections of the report are displayed. `--verbose` enables all of them. + +| Option | Description | +|:---|:---| +| `--dbstat` / `--no-dbstat` | Print database information | +| `--tbstat` / `--no-tbstat` | Print table information | +| `--colstat` / `--no-colstat` | Print column information | +| `--idxstat` / `--no-idxstat` | Print index information | +| `--sysstat` / `--no-sysstat` | Print system stats | +| `--pfstat` / `--no-pfstat` | Print Performance Schema info | +| `--plugininfo` / `--no-plugininfo` | Print plugin information | +| `--myisamstat` / `--no-myisamstat` | Print MyISAM stats | +| `--structstat` / `--no-structstat` | Print table structures, naming conventions, and modeling analysis | + +### Output Filtering + +| Option | Description | +|:---|:---| +| `--nobad` / `--no-nobad` | Remove negative/suggestion responses | +| `--nogood` / `--no-nogood` | Remove OK responses | +| `--noinfo` / `--no-noinfo` | Remove informational responses | + +### Examples + +```bash +# Show only problems (filter out OK and info) +perl mysqltuner.pl --nogood --noinfo + +# Selective stats +perl mysqltuner.pl --dbstat --idxstat --pfstat + +# Debug with pattern filtering +perl mysqltuner.pl --debug --dbgpattern="InnoDB|buffer" + +# Non-dedicated server (shared hosting) +perl mysqltuner.pl --nondedicated +``` - MySQLTuner 2.8.42 - MySQL High Performance Tuning Script +--- -# IMPORTANT USAGE GUIDELINES +## MISCELLANEOUS OPTIONS + +| Option | Description | +|:---|:---| +| `--help` (`-?`) | Show help message | +| `--noask` / `--no-noask` | Don't ask for confirmation | +| `--defaultarch <32\|64>` | Default architecture (default: 64) | +| `--bannedports

` | Ports banned, separated by comma | +| `--maxportallowed ` | Number of open ports allowable | +| `--ignore-tables ` | Tables to ignore, comma-separated | +| `--max-password-checks ` | Max password checks from dictionary (default: 100) | -To run the script with the default options, run the script without arguments -Allow MySQL server to run for at least 24-48 hours before trusting suggestions -Some routines may require root level privileges (script will provide warnings) -You must provide the remote server's total memory when connecting to other servers - -# OPTIONS - -See `mysqltuner --help` for a full list of available options and their categories. - -# VERSION - -Version 2.8.42 -=head1 PERLDOC - -You can find documentation for this module with the perldoc command. - - perldoc mysqltuner +--- ## INTERNALS -[https://github.com/jmrenouard/MySQLTuner-perl/blob/master/INTERNALS.md](https://github.com/jmrenouard/MySQLTuner-perl/blob/master/INTERNALS.md) - - Internal documentation - -# AUTHORS - -Major Hayden - major@mhtx.net -Jean-Marie Renouard - jmrenouard@gmail.com - -# CONTRIBUTORS - -- Matthew Montgomery -- Paul Kehrer -- Dave Burgess -- Jonathan Hinds -- Mike Jackson -- Nils Breunese -- Shawn Ashlee -- Luuk Vosslamber -- Ville Skytta -- Trent Hornibrook -- Jason Gill -- Mark Imbriaco -- Greg Eden -- Aubin Galinotti -- Giovanni Bechis -- Bill Bradford -- Ryan Novosielski -- Michael Scheidell -- Blair Christensen -- Hans du Plooy -- Victor Trac -- Everett Barnes -- Tom Krouper -- Gary Barrueto -- Simon Greenaway -- Adam Stein -- Isart Montane -- Baptiste M. -- Cole Turner -- Daniel Lewart -- Jason Gill -- Jean-Marie Renouard -- Major Hayden -- Matthew Montgomery -- Stephan GroBberndt -- Christian Loos -- Long Radix - -# SUPPORT - -Bug reports, feature requests, and downloads at http://mysqltuner.pl/ - -Bug tracker can be found at https://github.com/jmrenouard/MySQLTuner-perl/issues - -Maintained by Jean-Marie Renouard (jmrenouard\\@gmail.com) - Licensed under GPL - -# SOURCE CODE - -[https://github.com/jmrenouard/MySQLTuner-perl/](https://github.com/jmrenouard/MySQLTuner-perl/) - - git clone https://github.com/jmrenouard/MySQLTuner-perl/.git - -# COPYRIGHT AND LICENSE +Detailed documentation of all checks and indicators: [INTERNALS.md](https://github.com/jmrenouard/MySQLTuner-perl/blob/master/INTERNALS.md) -Copyright (C) 2006-2026 Major Hayden - major@mhtx.net -\# Copyright (C) 2015-2026 Jean-Marie Renouard - jmrenouard@gmail.com +## AUTHORS -For the latest updates, please visit http://mysqltuner.pl/ +- Major Hayden - major@mhtx.net +- Jean-Marie Renouard - jmrenouard@gmail.com -Git repository available at https://github.com/jmrenouard/MySQLTuner-perl/ +## LICENSE -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. +Copyright (C) 2006-2026 Major Hayden & Jean-Marie Renouard -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +Licensed under GPL v3. See [LICENSE](https://www.gnu.org/licenses/gpl-3.0.html). - See the GNU General Public License for more details. +## SOURCE CODE -You should have received a copy of the GNU General Public License -along with this program. If not, see <https://www.gnu.org/licenses/>. +- Repository: [https://github.com/jmrenouard/MySQLTuner-perl/](https://github.com/jmrenouard/MySQLTuner-perl/) +- Bug tracker: [https://github.com/jmrenouard/MySQLTuner-perl/issues](https://github.com/jmrenouard/MySQLTuner-perl/issues) diff --git a/build/audit_logs.pl b/build/audit_logs.pl index f2fa94ed8..4bf03f9be 100755 --- a/build/audit_logs.pl +++ b/build/audit_logs.pl @@ -30,7 +30,7 @@ find( sub { - return unless $_ eq 'execution.log'; + return unless $_ eq 'execution.log' || $_ eq 'mysqltuner_output.txt'; my $file_path = $File::Find::name; if ($verbose) { @@ -56,7 +56,7 @@ if ($line =~ /Syntax error/i || $line =~ /unexpected/i) { push @anomalies, { file => $file_path, line => $line_num, type => 'Syntax Anomaly', content => $line }; } - if ( ($line =~ /uninitialized value/i || $line =~ /deprecated/i) && $line !~ /(?:✔|\[OK\])/ ) { + if ( ($line =~ /uninitialized value/i || $line =~ /deprecated/i) && $line !~ /(?:✔|\[OK\])/ && $line !~ /uses DEPRECATED/ && $line !~ /uses DISABLED/ ) { push @anomalies, { file => $file_path, line => $line_num, type => 'Perl Warning', content => $line }; } } diff --git a/build/audit_tests.pl b/build/audit_tests.pl new file mode 100755 index 000000000..377388472 --- /dev/null +++ b/build/audit_tests.pl @@ -0,0 +1,174 @@ +#!/usr/bin/env perl + +use strict; +use warnings; + +# MySQLTuner Test Output Auditor +# Purpose: Run prove and scan its output for subtle Perl warnings, typos, and syntax errors. + +my $cmd = $ARGV[0] || $ENV{AUDIT_TEST_CMD} || 'prove -r tests/'; + +# --- Phase 1: Compile-time syntax check and static analysis --- +print "Performing compile-time syntax checks...\n"; +my @files_to_check = ( + 'mysqltuner.pl', + 'tests/MySQLTuner/TestHelper.pm', + glob("tests/*.t") +); + +my @syntax_errors; +my @syntax_warnings; + +foreach my $file (@files_to_check) { + next unless -f $file; + open(my $ch, '-|', "perl -I. -Itests -wc \"$file\" 2>&1") or do { + push @syntax_errors, { file => $file, content => "Failed to execute perl -wc: $!" }; + next; + }; + + my $has_error = 0; + while (my $line = <$ch>) { + chomp $line; + next if $line =~ /syntax OK$/; + + if ($line =~ /syntax error|Compilation failed|Can't locate|Undefined subroutine/i) { + push @syntax_errors, { file => $file, content => $line }; + $has_error = 1; + } + elsif ($line =~ /possible typo|redefined|prototype mismatch|masks earlier declaration|redeclared/i) { + # Skip known compile-time warning categories that are normal for test mocks + next; + } + else { + push @syntax_warnings, { file => $file, content => $line }; + } + } + close($ch); + + my $exit_val = $? >> 8; + if ($exit_val != 0 && !$has_error) { + push @syntax_errors, { file => $file, content => "Compile check failed with exit code $exit_val" }; + } +} + +if (@syntax_errors) { + print "\n[!] Compile Check Failed: Found " . scalar(@syntax_errors) . " compile-time syntax errors/failures:\n"; + foreach my $err (@syntax_errors) { + printf(" - %s: %s\n", $err->{file}, $err->{content}); + } + exit 1; +} + +if (@syntax_warnings) { + my %warnings_by_file; + foreach my $warn (@syntax_warnings) { + push @{$warnings_by_file{$warn->{file}}}, $warn->{content}; + } + + print "\n[!] Compile Check Warnings: Detected " . scalar(@syntax_warnings) . " compile-time warnings/typos:\n"; + foreach my $file (sort keys %warnings_by_file) { + my $count = scalar(@{$warnings_by_file{$file}}); + print " - $file: $count warnings\n"; + + my $display_limit = 3; + my $displayed = 0; + foreach my $content (@{$warnings_by_file{$file}}) { + print " * $content\n"; + $displayed++; + if ($displayed >= $display_limit && $count > $display_limit) { + print " * ... and " . ($count - $display_limit) . " more warnings\n"; + last; + } + } + } + print "\n"; +} else { + print "[OK] Compile Check: All files parsed cleanly.\n\n"; +} + +# --- Phase 2: Run test suite and audit runtime output --- +print "Executing test suite: $cmd\n"; + +open(my $ph, '-|', "$cmd 2>&1") or die "Failed to execute: $cmd: $!"; + +my @anomalies; +my @warnings; +my $line_num = 0; + +while (my $line = <$ph>) { + print $line; # Output in real-time + $line_num++; + + # Scan for Perl warnings and errors + if ($line =~ /Use of uninitialized value/i) { + push @warnings, { type => 'Uninitialized Value', content => $line, line => $line_num }; + } + elsif ($line =~ /possible typo/i && $line !~ /tests\//i) { + push @warnings, { type => 'Possible Typo', content => $line, line => $line_num }; + } + elsif ($line =~ /syntax error/i) { + push @anomalies, { type => 'Syntax Error', content => $line, line => $line_num }; + } + elsif ($line =~ /Compilation failed/i) { + push @anomalies, { type => 'Compilation Failure', content => $line, line => $line_num }; + } + elsif ($line =~ /Can't locate/i) { + push @anomalies, { type => 'Missing Dependency / Location Error', content => $line, line => $line_num }; + } + elsif ($line =~ /Can't call method|Can't use/i) { + push @anomalies, { type => 'Runtime Invocation Error', content => $line, line => $line_num }; + } + elsif ($line =~ /Undefined subroutine/i) { + push @anomalies, { type => 'Undefined Subroutine', content => $line, line => $line_num }; + } + elsif ($line =~ /Bail out!/i) { + push @anomalies, { type => 'Test Execution Bail Out', content => $line, line => $line_num }; + } + elsif ($line =~ /died at|died\b/i) { + push @anomalies, { type => 'Fatal Exception', content => $line, line => $line_num }; + } + elsif ($line =~ /Modification of a read-only value|Attempt to free unreferenced scalar|divided by zero/i) { + push @anomalies, { type => 'Perl Runtime Violation', content => $line, line => $line_num }; + } + elsif ($line =~ /Out of memory/i) { + push @anomalies, { type => 'Out Of Memory Error', content => $line, line => $line_num }; + } + elsif ($line =~ /Dubious, test returned/i || $line =~ /Failed test/i) { + push @anomalies, { type => 'Test Failure', content => $line, line => $line_num }; + } +} +close($ph); + +my $exit_code = $? >> 8; + +if (@anomalies) { + print "\n[!] Test Audit Gate: Found " . scalar(@anomalies) . " execution errors/failures:\n"; + foreach my $anomaly (@anomalies) { + chomp $anomaly->{content}; + printf(" - [%s] %s (Output line %d)\n", $anomaly->{type}, $anomaly->{content}, $anomaly->{line}); + } + exit 1; +} + +if (@warnings) { + print "\n[!] Test Audit Gate: Detected " . scalar(@warnings) . " warnings/notices:\n"; + # Limit warnings display to top 20 to avoid log bloat + my $count = 0; + foreach my $warning (@warnings) { + chomp $warning->{content}; + printf(" - [%s] %s (Output line %d)\n", $warning->{type}, $warning->{content}, $warning->{line}); + $count++; + if ($count >= 20) { + print " - ... and " . (scalar(@warnings) - 20) . " more warnings.\n"; + last; + } + } +} + +if ($exit_code != 0) { + print "\n[!] Test suite failed with exit code: $exit_code\n"; + exit $exit_code; +} + +print "\n[OK] Test Audit Gate: No execution errors, typos, or anomalies detected in test output.\n"; +exit 0; diff --git a/build/get_supported_envs.pl b/build/get_supported_envs.pl index de2e64959..9624d1eb0 100755 --- a/build/get_supported_envs.pl +++ b/build/get_supported_envs.pl @@ -14,7 +14,7 @@ sub parse_support_file { open my $fh, '<', $file or die "Cannot open $file: $!\n"; while (my $line = <$fh>) { # Format: | 8.4 | Supported | 2024-04-30 | 2032-04-30 | - if ($line =~ /\|\s*([\d\.]+)\s*\|\s*Supported\s*\|/) { + if ($line =~ /\|\s*([\d\.]+)\s*\|[^|]*\|[^|]*\|\s*Supported\s*\|/) { my $version = $1; $version =~ s/\.//g; # Remove dots (e.g. 8.4 -> 84, 10.11 -> 1011) push @configs, "$prefix$version"; diff --git a/build/parallel_test.sh b/build/parallel_test.sh new file mode 100755 index 000000000..8a7a1cccc --- /dev/null +++ b/build/parallel_test.sh @@ -0,0 +1,177 @@ +#!/bin/bash +# ================================================================================== +# Script: parallel_test.sh +# Description: Runs MySQLTuner laboratory validation tests in parallel. +# ================================================================================== + +PROJECT_ROOT=$(pwd) +EXAMPLES_DIR="$PROJECT_ROOT/examples" +VENDOR_DIR="$PROJECT_ROOT/vendor" +DATE_TAG=$(date +%Y%m%d_%H%M%S) +CVE_FILE="$PROJECT_ROOT/vulnerabilities.csv" + +# Gathers supported configurations +CONFIGS=$(perl build/get_supported_envs.pl) +echo "Supported configurations: $CONFIGS" + +# Cleanup function to run at the end or on interrupt +cleanup() { + echo "🧹 Cleaning up parallel test containers..." + for config in $CONFIGS; do + docker rm -f "mysqltuner-parallel-$config" >/dev/null 2>&1 + done +} +trap cleanup EXIT + +# Setup vendor directories +mkdir -p "$EXAMPLES_DIR" +if [ ! -d "$VENDOR_DIR/multi-db-docker-env" ]; then + git clone "https://github.com/jmrenouard/multi-db-docker-env" "$VENDOR_DIR/multi-db-docker-env" +fi +if [ ! -d "$VENDOR_DIR/test_db" ]; then + git clone "https://github.com/jmrenouard/test_db" "$VENDOR_DIR/test_db" +fi + +# Port counter and container list +port_base=33060 +declare -A config_ports +declare -A config_images + +# Setup mappings +idx=0 +for config in $CONFIGS; do + port=$((port_base + idx)) + config_ports[$config]=$port + + image="mysql:8.0" + if [[ "$config" =~ ^mysql([0-9]+)$ ]]; then + ver="${BASH_REMATCH[1]}" + image="mysql:${ver:0:1}.${ver:1}" + elif [[ "$config" =~ ^mariadb([0-9]+)$ ]]; then + ver="${BASH_REMATCH[1]}" + if [[ "${ver:0:1}" == "5" ]]; then + image="mariadb:${ver:0:1}.${ver:1}" + else + image="mariadb:${ver:0:2}.${ver:2}" + fi + elif [[ "$config" =~ ^percona([0-9]+)$ ]]; then + ver="${BASH_REMATCH[1]}" + image="percona/percona-server:${ver:0:1}.${ver:1}" + fi + config_images[$config]=$image + idx=$((idx + 1)) +done + +# Start all containers in parallel +echo "🚀 Starting all containers in parallel..." +for config in $CONFIGS; do + port=${config_ports[$config]} + image=${config_images[$config]} + echo " Starting $config on port $port using image $image..." + docker run -d \ + --name "mysqltuner-parallel-$config" \ + -p "$port:3306" \ + --cpus="1.0" \ + --memory="1024m" \ + -e MYSQL_ROOT_PASSWORD=mysqltuner_test \ + -e MARIADB_ROOT_PASSWORD=mysqltuner_test \ + -e MYSQL_ROOT_HOST="%" \ + -v "$VENDOR_DIR/multi-db-docker-env/conf/pfs.cnf:/etc/mysql/conf.d/pfs.cnf" \ + -v "$VENDOR_DIR/multi-db-docker-env/conf/pfs.cnf:/etc/my.cnf.d/pfs.cnf" \ + "$image" >/dev/null 2>&1 & +done +wait + +# Wait for all databases to become ready in parallel +echo "⏳ Waiting for databases to initialize..." +for config in $CONFIGS; do + port=${config_ports[$config]} + ( + timeout=120 + count=0 + until mysqladmin -h 127.0.0.1 -P "$port" -u root -pmysqltuner_test ping >/dev/null 2>&1; do + sleep 2 + count=$((count + 2)) + if [ $count -ge $timeout ]; then + echo "❌ Timeout waiting for $config on port $port" + exit 1 + fi + done + echo "✅ $config on port $port is ready" + ) & +done +wait + +# Inject data in parallel +echo "💉 Injecting test databases (sakila/employees)..." +for config in $CONFIGS; do + port=${config_ports[$config]} + ( + # Inject employees (skip for mysql96 due to nested source regression) + if [ "$config" != "mysql96" ]; then + mysql -h 127.0.0.1 -P "$port" -u root -pmysqltuner_test < "$VENDOR_DIR/test_db/employees/employees.sql" >/dev/null 2>&1 + fi + # Inject Sakila + mysql -h 127.0.0.1 -P "$port" -u root -pmysqltuner_test < "$VENDOR_DIR/test_db/sakila/sakila-mv-schema.sql" >/dev/null 2>&1 + mysql -h 127.0.0.1 -P "$port" -u root -pmysqltuner_test < "$VENDOR_DIR/test_db/sakila/sakila-mv-data.sql" >/dev/null 2>&1 + echo "✅ Data injected into $config" + ) & +done +wait + +# Execute MySQLTuner in parallel +echo "🧪 Running MySQLTuner test suite in parallel..." +for config in $CONFIGS; do + port=${config_ports[$config]} + ( + target_dir="$EXAMPLES_DIR/${DATE_TAG}_$config" + mkdir -p "$target_dir/Standard" "$target_dir/Container" "$target_dir/Dumpdir" "$target_dir/Schemadir" + + # Standard Mode + perl mysqltuner.pl --host 127.0.0.1 --port "$port" --user root --pass mysqltuner_test --verbose --noask --cvefile "$CVE_FILE" --outputfile "$target_dir/Standard/mysqltuner_output.txt" > "$target_dir/Standard/execution.log" 2>&1 + + # Container Mode + perl mysqltuner.pl --container docker:"mysqltuner-parallel-$config" --user root --pass mysqltuner_test --verbose --noask --cvefile "$CVE_FILE" --outputfile "$target_dir/Container/mysqltuner_output.txt" > "$target_dir/Container/execution.log" 2>&1 + + # Dumpdir Mode + perl mysqltuner.pl --host 127.0.0.1 --port "$port" --user root --pass mysqltuner_test --verbose --noask --dumpdir "$target_dir/Dumpdir/dumps" --cvefile "$CVE_FILE" --outputfile "$target_dir/Dumpdir/mysqltuner_output.txt" > "$target_dir/Dumpdir/execution.log" 2>&1 + + # Schemadir Mode + perl mysqltuner.pl --host 127.0.0.1 --port "$port" --user root --pass mysqltuner_test --verbose --noask --schemadir "$target_dir/Schemadir/schemas" --cvefile "$CVE_FILE" --outputfile "$target_dir/Schemadir/mysqltuner_output.txt" > "$target_dir/Schemadir/execution.log" 2>&1 + + echo "✅ MySQLTuner tests completed for $config" + ) & +done +wait + +# Audit logs for failures +echo "🔍 Running log checker..." +TAP_FILE="$EXAMPLES_DIR/${DATE_TAG}_parallel_test.tap" +echo "1..$(echo $CONFIGS | wc -w)" > "$TAP_FILE" +idx=1 +overall_success=true +for config in $CONFIGS; do + target_dir="$EXAMPLES_DIR/${DATE_TAG}_$config" + perl build/audit_logs.pl --dir "$target_dir" >/dev/null 2>&1 + if [ $? -eq 0 ]; then + echo "ok $idx - $config" >> "$TAP_FILE" + echo "ok $idx - $config" + else + echo "not ok $idx - $config" >> "$TAP_FILE" + echo "not ok $idx - $config" + overall_success=false + fi + idx=$((idx + 1)) +done + +echo "📝 Compiled TAP Report written to $TAP_FILE" + +if [ "$overall_success" = "true" ]; then + exit_code=0 + echo "🎉 Parallel test execution completed successfully with no anomalies!" +else + exit_code=1 + echo "❌ Anomalies/failures detected during test validation!" +fi + +exit $exit_code diff --git a/build/test_envs.sh b/build/test_envs.sh index 184d1c6fd..40a9c40ed 100755 --- a/build/test_envs.sh +++ b/build/test_envs.sh @@ -203,6 +203,7 @@ check_exit_code() { return 0 } +# Generate unified HTML report # Generate unified HTML report generate_report() { local target_dir=$1 @@ -213,6 +214,11 @@ generate_report() { local db_list=$6 local repro_cmds=$7 local current_scenario=$8 + local duration_startup=${9:-0} + local duration_ready=${10:-0} + local duration_inject=${11:-0} + local db_total_rows=${12:-0} + local db_total_size=${13:-0} log_step "Generating consolidated HTML report for $name ($current_scenario)..." @@ -270,6 +276,437 @@ generate_report() { scenario_bar+="" fi + # Scenario Descriptions + local scenario_desc="" + case "$current_scenario" in + Standard) + scenario_desc="Performs local network connection auditing using standard TCP/IP transport (loopback) to query database engine metrics, system status variables, and global performance indicators." + ;; + Container) + scenario_desc="Audits system configurations using native container socket transport (e.g. docker:container_name), skipping local TCP connections to inspect runtime environment contexts directly from the host system." + ;; + Dumpdir) + scenario_desc="Executes off-line schema and configuration analysis by exporting status variables and system variables to a temporary dump directory, validating remote auditing capabilities without a live database connection." + ;; + Schemadir) + scenario_desc="Performs structural modeling schema audits, analyzing table designs, constraints, indexes, data types, and naming conventions by dumping schema layouts without querying full datasets." + ;; + *) + scenario_desc="Custom audit scenario execution." + ;; + esac + + local desc_html="" + if [ -n "$current_scenario" ]; then + desc_html="

+

Scenario Description: $current_scenario

+

$scenario_desc

+
" + fi + + # Step Breakdown / Execution Timeline HTML + local total_time ratio_startup ratio_ready ratio_inject ratio_tuner breakdown_html="" + if [ "$duration_startup" -gt 0 ] || [ "$duration_ready" -gt 0 ] || [ "$duration_inject" -gt 0 ]; then + total_time=$((duration_startup + duration_ready + duration_inject + exec_time)) + [ $total_time -eq 0 ] && total_time=1 + ratio_startup=$((duration_startup * 100 / total_time)) + ratio_ready=$((duration_ready * 100 / total_time)) + ratio_inject=$((duration_inject * 100 / total_time)) + ratio_tuner=$((exec_time * 100 / total_time)) + + breakdown_html="
+
+

+ Execution Timeline & Step Breakdown +

+
+
+
" + [ $duration_startup -gt 0 ] && breakdown_html+="
" + [ $duration_ready -gt 0 ] && breakdown_html+="
" + [ $duration_inject -gt 0 ] && breakdown_html+="
" + [ $exec_time -gt 0 ] && breakdown_html+="
" + breakdown_html+="
+ +
+
+
+ + Container Startup + + ${duration_startup}s (${ratio_startup}%) +
+
+
+
+
+
+
+ + Readiness Check + + ${duration_ready}s (${ratio_ready}%) +
+
+
+
+
+
+
+ + Data Injection + + ${duration_inject}s (${ratio_inject}%) +
+
+
+
+
+
+
+ + MySQLTuner Run + + ${exec_time}s (${ratio_tuner}%) +
+
+
+
+
+
+
+
" + fi + # Run log audit + local audit_status_icon="" + local audit_status_text="No anomalies or execution errors detected during MySQLTuner runtime." + local audit_status_class="border-green-500 bg-green-950/20 text-green-400" + local has_errors=false + + # Check for Performance Schema Disabled + local err_ps=$(grep -i "Performance_schema should be activated" "$target_dir/execution.log" "$target_dir/mysqltuner_output.txt" 2>/dev/null) + # Check for SQL Execution Failure + local err_sql=$(grep -i "FAIL Execute SQL" "$target_dir/execution.log" "$target_dir/mysqltuner_output.txt" 2>/dev/null) + # Check for Syntax Anomaly + local err_syntax=$(grep -i -E "Syntax error|unexpected" "$target_dir/execution.log" "$target_dir/mysqltuner_output.txt" 2>/dev/null) + # Check for Perl Warnings + local err_perl=$(grep -i -E "uninitialized value|deprecated" "$target_dir/execution.log" "$target_dir/mysqltuner_output.txt" 2>/dev/null | grep -v -i -E "✔|\[OK\]|uses DEPRECATED|uses DISABLED") + + local err_list="" + if [ -n "$err_ps" ]; then + has_errors=true + err_list+="
[Performance Schema Disabled]
$err_ps
" + fi + if [ -n "$err_sql" ]; then + has_errors=true + err_list+="
[SQL Execution Failure]
$err_sql
" + fi + if [ -n "$err_syntax" ]; then + has_errors=true + err_list+="
[Syntax Anomaly]
$err_syntax
" + fi + if [ -n "$err_perl" ]; then + has_errors=true + err_list+="
[Perl Warning / Deprecation]
$err_perl
" + fi + + if [ "$has_errors" = true ]; then + audit_status_icon="" + audit_status_text="Anomalies or syntax warnings detected in MySQLTuner execution logs." + audit_status_class="border-red-500 bg-red-950/20 text-red-400" + fi + + local audit_log_panel="
+
+

+ Runtime Audit & Failure Analysis +

+
+
+
+ $audit_status_icon +
+

$audit_status_text

+
+
" + if [ "$has_errors" = true ]; then + audit_log_panel+="
+

Detected Anomalies Log

+ $err_list +
" + fi + audit_log_panel+="
+
" + + # Table of Produced Files + local main_files_html="" + local ps_files_html="" + local ifs_files_html="" + local sys_files_html="" + + add_file_row() { + local path=$1; local label=$2; local desc=$3 + local full_path="$target_dir/$path" + if [ ! -f "$full_path" ]; then + # Check relative to base if not absolute + full_path="$path" + fi + [ -f "$full_path" ] || return + + local row=" + + + $label + $(basename "$path") + + + $desc + " + + local base=$(basename "$path") + if [[ "$base" =~ ^ps_ ]]; then + ps_files_html+="$row" + elif [[ "$base" =~ ^ifs_ ]]; then + ifs_files_html+="$row" + elif [[ "$base" =~ ^sys ]]; then + sys_files_html+="$row" + else + main_files_html+="$row" + fi + } + + add_file_row "report.html" "HTML Report" "The consolidated interactive dashboard and timing report." + add_file_row "mysqltuner_output.txt" "MySQLTuner Raw Output" "The plain text output generated by MySQLTuner execution." + add_file_row "execution.log" "Execution Log" "Standard output and standard error traces captured during the run." + add_file_row "docker_start.log" "Docker Startup Log" "Logs from the Docker engine container startup." + add_file_row "db_injection.log" "DB Injection Log" "Logs from the sample database employees schema and data import." + add_file_row "container_logs.log" "Container Runtime Logs" "Standard output/error logs queried from the database container." + add_file_row "container_inspect.json" "Container Metadata" "JSON metadata details retrieved from docker inspect." + + # Helper subroutine get_dynamic_desc in Perl + local perl_desc_sub=' + sub get_dynamic_desc { + my ($f) = @_; + my $base = File::Basename::basename($f); + if (!-e $f) { + return "Snapshot file."; + } + + my $desc = "Snapshot file."; + if ($base =~ /^naming_convention_deviations\.csv(?:\.gz)?$/) { + $desc = "List of database schema tables and columns that violate naming conventions (e.g. plural names, case issues)."; + } + elsif ($base =~ /^primary_key_issues\.csv(?:\.gz)?$/) { + $desc = "Audit report highlighting tables with missing, misnamed, or suboptimal surrogate primary keys."; + } + elsif ($base =~ /^missing_foreign_keys\.csv(?:\.gz)?$/) { + $desc = "List of table columns whose names suggest they should be foreign keys, but no foreign key constraints exist."; + } + elsif ($base =~ /^json_columns_without_virtual\.csv(?:\.gz)?$/) { + $desc = "Audit of JSON columns in the database that do not have associated virtual generated columns for indexing."; + } + elsif ($base =~ /^insecure_authentication_plugins\.csv(?:\.gz)?$/) { + $desc = "List of database user accounts configured with legacy or insecure authentication plugins."; + } + elsif ($base =~ /^ssl_issues\.csv(?:\.gz)?$/) { + $desc = "Security report detailing active SSL/TLS vulnerabilities or missing secure configurations."; + } + elsif ($base =~ /^user_with_general_wildcard\.csv(?:\.gz)?$/) { + $desc = "Accounts configured with a general wildcard host ('%'), which presents security risks."; + } + elsif ($base =~ /^columns_utf8\.csv(?:\.gz)?$/) { + $desc = "Inventory of table columns that correctly use UTF-8/UTF8MB4 character sets."; + } + elsif ($base =~ /^columns_non_utf8\.csv(?:\.gz)?$/) { + $desc = "Audit list of columns using legacy or non-UTF-8 character encodings (e.g. latin1)."; + } + elsif ($base =~ /^fulltext_columns\.csv(?:\.gz)?$/) { + $desc = "List of columns that have full-text indexes configured."; + } + elsif ($base =~ /^non_mysqld_processes\.csv(?:\.gz)?$/) { + $desc = "List of running system processes not related to mysqld that are consuming CPU/RAM resources."; + } + elsif ($base =~ /^fragmented_tables\.csv(?:\.gz)?$/) { + $desc = "Tables with fragmented data space."; + } + elsif ($base =~ /^tables_non_innodb\.csv(?:\.gz)?$/) { + $desc = "Audit of database tables utilizing storage engines other than InnoDB."; + } + elsif ($base =~ /^tables_without_primary_keys\.csv(?:\.gz)?$/) { + $desc = "Audit list of tables lacking a primary key constraint."; + } + elsif ($base =~ /^raw_mysqltuner\.txt$/) { + $desc = "Plain text unformatted output captured from MySQLTuner execution."; + } + elsif ($base =~ /^ifs_(.*)\.csv(?:\.gz)?$/) { + my $table = $1; + $desc = "Information Schema table dump for INFORMATION_SCHEMA.$table."; + } + elsif ($base =~ /^ps_(.*)\.csv(?:\.gz)?$/) { + my $table = $1; + $desc = "Performance Schema table dump for performance_schema.$table."; + } + elsif ($base =~ /^sys_x\$(.*)\.csv(?:\.gz)?$/) { + my $table = $1; + $desc = "Sys Schema raw/unformatted table view for sys.x$$table."; + } + elsif ($base =~ /^sys_(.*)\.csv(?:\.gz)?$/) { + my $table = $1; + $desc = "Sys Schema table view for sys.$table."; + } + elsif ($base =~ /\.sql(?:\.gz)?$/) { + if (-z $f) { + $desc = "SQL database schema script."; + } else { + my @tables; + my $fh; + if ($f =~ /\.gz$/) { + open($fh, "gzip -dc \x27$f\x27 |") or $desc = "SQL script."; + } else { + open($fh, "<", $f) or $desc = "SQL script."; + } + if (defined $fh) { + my $lines_read = 0; + while (my $line = <$fh>) { + if ($line =~ /CREATE TABLE\s+[`\x27\"]?(\w+)[`\x27\"]?/i) { + push @tables, $1; + } + $lines_read++; + last if @tables >= 5 || $lines_read > 500; + } + close($fh); + if (@tables) { + my $t_list = join(", ", @tables); + $desc = "SQL DDL schema definitions for tables: $t_list" . (scalar(@tables) >= 5 ? "..." : "") . "."; + } else { + $desc = "SQL database schema script."; + } + } + } + } + elsif ($base =~ /\.md$/) { + if (-z $f) { + $desc = "Markdown documentation."; + } else { + my $fh; + if (open($fh, "<", $f)) { + my $header = <$fh>; + close($fh); + if ($header) { + chomp($header); + $header =~ s/^#+\s*//; + $desc = "Markdown documentation: $header."; + } else { + $desc = "Markdown documentation."; + } + } else { + $desc = "Markdown documentation."; + } + } + } + elsif ($base =~ /\.txt$/) { + $desc = "Configuration or metric metadata log."; + } + + if (-z $f) { + if ($base =~ /\.csv(?:\.gz)?$/) { + $desc .= " (Empty - no issues/records detected)"; + } else { + $desc .= " (Empty)"; + } + } + + return $desc; + } + ' + + # Dynamically find and list all files in dumps/ if it exists + if [ -d "$target_dir/dumps" ]; then + while IFS='|' read -r rel_path label desc; do + add_file_row "$rel_path" "$label" "$desc" + done < <(perl -MFile::Basename -e ' + my $dir = shift; + opendir(my $dh, $dir) or return; + my @files = sort grep { -f "$dir/$_" } readdir($dh); + closedir($dh); + + for my $base (@files) { + my $file = "$dir/$base"; + next if $base eq "manifest.json" || $base eq "metadata.txt"; + + my $rel_path = "dumps/$base"; + my $label = "MySQL Dump: $base"; + if ($base =~ /naming_convention_deviations\.csv/) { + $label = "Naming Conventions CSV"; + } elsif ($base =~ /primary_key_issues\.csv/) { + $label = "Primary Key Issues CSV"; + } elsif ($base =~ /missing_foreign_keys\.csv/) { + $label = "Missing Foreign Keys CSV"; + } elsif ($base =~ /json_columns_without_virtual\.csv/) { + $label = "JSON Virtual Columns CSV"; + } + + my $desc = get_dynamic_desc($file); + print "$rel_path|$label|$desc\n"; + } + '"$perl_desc_sub" "$target_dir/dumps") + fi + + # Dynamically find and list all files in schemas/ if it exists + if [ -d "$target_dir/schemas" ]; then + while IFS='|' read -r rel_path label desc; do + add_file_row "$rel_path" "$label" "$desc" + done < <(perl -MFile::Basename -e ' + my $dir = shift; + opendir(my $dh, $dir) or return; + my @files = sort grep { -f "$dir/$_" } readdir($dh); + closedir($dh); + + for my $base (@files) { + my $file = "$dir/$base"; + my $rel_path = "schemas/$base"; + my $label = "Schema Layout: $base"; + + my $desc = get_dynamic_desc($file); + print "$rel_path|$label|$desc\n"; + } + '"$perl_desc_sub" "$target_dir/schemas") + fi + + # Helper function to render a table panel + render_table_panel() { + local title=$1; local icon=$2; local color=$3; local content=$4 + [ -z "$content" ] && return + + echo "
+
+

+ $title +

+
+
+ + + + + + + + + $content + +
Artifact / FileDescription
+
+
" + } + + local main_table=$(render_table_panel "General Logs & Artifacts" "fa-file-alt" "text-yellow-400" "$main_files_html") + local ps_table=$(render_table_panel "Performance Schema Files" "fa-tachometer-alt" "text-orange-400" "$ps_files_html") + local ifs_table=$(render_table_panel "Information Schema Files" "fa-info-circle" "text-blue-400" "$ifs_files_html") + local sys_table=$(render_table_panel "Sys Schema Files" "fa-cogs" "text-green-400" "$sys_files_html") + + local produced_files_panel="${main_table}${ps_table}${ifs_table}${sys_table}" + cat < "$target_dir/report.html" @@ -295,6 +732,8 @@ generate_report() { $scenario_bar + $desc_html +
@@ -317,6 +756,8 @@ generate_report() {
+ $breakdown_html +
@@ -324,7 +765,7 @@ generate_report() {

Environment Details

-
+

Database List

@@ -340,6 +781,13 @@ generate_report() {
  • Force RAM: ${FORCEMEM_VAL:-"Auto"}
  • +
    +

    Storage Metrics (information_schema)

    +
      +
    • Total Rows: $(printf "%'d" ${db_total_rows:-0} 2>/dev/null || echo ${db_total_rows:-0})
    • +
    • Total Size: ${db_total_size:-0} MB
    • +
    +
    @@ -366,6 +814,10 @@ generate_report() { $(render_panel "execution.log" "Full Execution Trace" "fa-file-code" "text-yellow-400") + + $audit_log_panel + + $produced_files_panel