Skip to main content

mysql

Administer MySQL/MariaDB databases. Configure replication and optimize performance. Use when managing MySQL deployments.

معلومات المصدر

المستودع
BagelHole/DevOps-Security-Agent-Skills
آخر نشاط في المصدر
٢٤ مارس ٢٠٢٦ في ٢٢:٠٢
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
١٬١٦٢
التفرعات
١٦٥

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
mysql
description
Administer MySQL/MariaDB databases. Configure replication and optimize performance. Use when managing MySQL deployments.
license
MIT
metadata
{"author":"devops-skills","version":"1.0"}
# MySQL / MariaDB Administer, optimize, and secure MySQL and MariaDB databases in development and production environments. ## When to Use - You need a mature, widely supported relational database. - Your stack depends on MySQL-specific features or compatibility (WordPress, Magento, many PHP frameworks). - You are setting up source-replica replication for read scaling. - You want to tune InnoDB for high-throughput transactional workloads. ## Prerequisites - Linux server (Debian/Ubuntu or RHEL-based) or Docker. - Root or sudo access for package installation. - Familiarity with SQL fundamentals. ## Installation and Setup ```bash # Debian / Ubuntu — MySQL 8 sudo apt update sudo apt install -y mysql-server # RHEL / Amazon Linux sudo dnf install -y mysql-server sudo systemctl enable --now mysqld # Run the secure installation wizard sudo mysql_secure_installation # Prompts: set root password, remove anonymous users, disable remote root, remove test db # Verify mysql --version sudo systemctl status mysql ``` ## Initial User and Database Setup ```bash sudo mysql -u root -p ``` ```sql -- Create a database CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- Create an application user with strong auth CREATE USER 'myapp'@'%' IDENTIFIED BY 'strong_password_here'; GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO 'myapp'@'%'; FLUSH PRIVILEGES; -- Verify SHOW GRANTS FOR 'myapp'@'%'; ``` ## mysql CLI Reference ```bash # Connect mysql -u myapp -p -h 127.0.0.1 mydb # Execute a single statement mysql -u myapp -p -e "SELECT COUNT(*) FROM orders;" mydb # Import a SQL file mysql -u myapp -p mydb < schema.sql # Export query results to CSV mysql -u myapp -p -e "SELECT * FROM users" mydb \ | tr '\t' ',' > users.csv ``` ``` -- Inside the mysql shell SHOW DATABASES; USE mydb; SHOW TABLES; DESCRIBE users; SHOW CREATE TABLE users\G SHOW PROCESSLIST; SHOW ENGINE INNODB STATUS\G ``` ## Configuration Tuning Edit `/etc/mysql/mysql.conf.d/mysqld.cnf` (or `/etc/my.cnf` on RHEL). ```ini [mysqld] # -- Networking -- bind-address = 0.0.0.0 max_connections = 300 wait_timeout = 600 interactive_timeout = 600 # -- InnoDB (most impactful settings) -- innodb_buffer_pool_size = 4G # ~70% of RAM on a dedicated server innodb_buffer_pool_instances = 4 # 1 per GB of pool (up to 64) innodb_log_file_size = 1G innodb_flush_log_at_trx_commit = 1 # 1 = ACID; 2 = faster, slight risk innodb_flush_method = O_DIRECT # avoids double buffering on Linux innodb_io_capacity = 2000 # raise for SSD innodb_io_capacity_max = 4000 # -- Query cache (disabled in MySQL 8, use ProxySQL or app cache) -- # query_cache_type = 0 # -- Logging -- slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 1 log_error = /var/log/mysql/error.log # -- Binary log (required for replication) -- server-id = 1 log_bin = /var/log/mysql/mysql-bin binlog_expire_logs_seconds = 604800 # 7 days sync_binlog = 1 # -- Character set -- character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci ``` ```bash # Apply changes sudo systemctl restart mysql # Verify a setting at runtime mysql -u root -p -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';" ``` ## Backup and Restore ### Logical Backups with mysqldump ```bash # Single database mysqldump -u root -p --single-transaction --routines --triggers \ mydb > /backups/mydb_$(date +%F).sql # All databases mysqldump -u root -p --all-databases --single-transaction \ > /backups/all_$(date +%F).sql # Compressed backup mysqldump -u root -p --single-transaction mydb \ | gzip > /backups/mydb_$(date +%F).sql.gz # Restore mysql -u root -p mydb < /backups/mydb_2025-01-15.sql # Restore compressed gunzip < /backups/mydb_2025-01-15.sql.gz | mysql -u root -p mydb ``` ### Physical Backups with Percona XtraBackup ```bash # Install sudo apt install -y percona-xtrabackup-80 # Full backup xtrabackup --backup --user=root --password=secret \ --target-dir=/backups/full_$(date +%F) # Prepare the backup (apply redo logs) xtrabackup --prepare --target-dir=/backups/full_2025-01-15 # Restore (stop MySQL first) sudo systemctl stop mysql sudo rm -rf /var/lib/mysql/* xtrabackup --move-back --target-dir=/backups/full_2025-01-15 sudo chown -R mysql:mysql /var/lib/mysql sudo systemctl start mysql ``` ### Incremental Backup with XtraBackup ```bash # Incremental based on the full backup xtrabackup --backup --user=root --password=secret \ --target-dir=/backups/inc_$(date +%F) \ --incremental-basedir=/backups/full_2025-01-15 # Prepare: apply full, then incremental xtrabackup --prepare --apply-log-only --target-dir=/backups/full_2025-01-15 xtrabackup --prepare --target-dir=/backups/full_2025-01-15 \ --incremental-dir=/backups/inc_2025-01-16 ``` ## Source-Replica Replication ### Source (Primary) ```ini # /etc/mysql/mysql.conf.d/mysqld.cnf [mysqld] server-id = 1 log_bin = /var/log/mysql/mysql-bin binlog_format = ROW ``` ```sql -- Create replication user CREATE USER 'replicator'@'10.0.0.%' IDENTIFIED BY 'repl_secret'; GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'10.0.0.%'; FLUSH PRIVILEGES; -- Get current binary log position SHOW MASTER STATUS\G ``` ### Replica ```ini # /etc/mysql/mysql.conf.d/mysqld.cnf [mysqld] server-id = 2 relay_log = /var/log/mysql/relay-bin read_only = ON ``` ```sql -- Point replica to source (use SHOW MASTER STATUS values) CHANGE REPLICATION SOURCE TO SOURCE_HOST = '10.0.0.1', SOURCE_USER = 'replicator', SOURCE_PASSWORD = 'repl_secret', SOURCE_LOG_FILE = 'mysql-bin.000003', SOURCE_LOG_POS = 154; START REPLICA; -- Verify SHOW REPLICA STATUS\G -- Check: Replica_IO_Running = Yes, Replica_SQL_Running = Yes, Seconds_Behind_Source = 0 ``` ## Monitoring Queries ```sql -- Connection statistics SHOW STATUS LIKE 'Threads_connected'; SHOW STATUS LIKE 'Max_used_connections'; -- InnoDB buffer pool hit ratio (should be > 99%) SELECT ROUND(100 - ( (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Innodb_buffer_pool_reads') / (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Innodb_buffer_pool_read_requests') ) * 100, 2) AS buffer_pool_hit_pct; -- Top 10 slow queries (requires performance_schema) SELECT DIGEST_TEXT, COUNT_STAR, AVG_TIMER_WAIT / 1e12 AS avg_sec FROM performance_schema.events_statements_summary_by_digest ORDER BY AVG_TIMER_WAIT DESC LIMIT 10; -- Table sizes SELECT table_name, ROUND(data_length / 1024 / 1024, 2) AS data_mb, ROUND(index_length / 1024 / 1024, 2) AS index_mb, table_rows FROM information_schema.tables WHERE table_schema = 'mydb' ORDER BY data_length DESC; -- Check replication lag SHOW REPLICA STATUS\G -- Look at Seconds_Behind_Source ``` ## Docker Compose Setup ```yaml # docker-compose.yml version: "3.9" services: mysql: image: mysql:8.0 restart: unless-stopped ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: rootpass MYSQL_DATABASE: mydb MYSQL_USER: myapp MYSQL_PASSWORD: secret volumes: - mysql_data:/var/lib/mysql - ./init.sql:/docker-entrypoint-initdb.d/init.sql command: > --innodb-buffer-pool-size=512M --max-connections=200 --slow-query-log=ON --long-query-time=1 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-prootpass"] interval: 10s timeout: 5s retries: 5 phpmyadmin: image: phpmyadmin:latest restart: unless-stopped ports: - "8080:80" environment: PMA_HOST: mysql PMA_USER: root PMA_PASSWORD: rootpass depends_on: mysql: condition: service_healthy volumes: mysql_data: ``` ```bash docker compose up -d mysql -h 127.0.0.1 -u myapp -psecret mydb ``` ## Maintenance Tasks ```bash # Optimize a fragmented table (locks the table briefly) mysql -u root -p -e "OPTIMIZE TABLE mydb.orders;" # Analyze tables to update statistics mysql -u root -p -e "ANALYZE TABLE mydb.orders;" # Check and repair a table mysql -u root -p -e "CHECK TABLE mydb.orders;" mysql -u root -p -e "REPAIR TABLE mydb.orders;" # Rotate slow query log sudo mv /var/log/mysql/slow.log /var/log/mysql/slow.log.old mysqladmin -u root -p flush-logs ``` ## Troubleshooting | Symptom | Likely Cause | Fix | |---|---|---| | `Too many connections` | Connection limit exceeded | Increase `max_connections`; use connection pooling (ProxySQL) | | Slow queries across the board | `innodb_buffer_pool_size` too small | Set to ~70% of available RAM and restart | | Replication stopped (`SQL_Running: No`) | Duplicate key or schema mismatch on replica | Check `SHOW REPLICA STATUS\G` error; skip or fix the row | | `Table is full` | Disk space exhausted or table limit hit | Free disk space; check `innodb_data_file_path` autoextend | | `Lock wait timeout exceeded` | Long-running transaction holding row locks | Identify with `SHOW ENGINE INNODB STATUS`; kill the blocking query | | High IOPS / disk usage | Redo log too small causing frequent flushes | Increase `innodb_log_file_size` (requires restart) | ## Related Skills - [postgresql](../postgresql/) - Alternative relational database - [database-backups](../database-backups/) - Automated backup strategies - [redis](../redis/) - Caching layer to reduce database load - [planetscale](../planetscale/) - Managed MySQL-compatible with branching
عرض على GitHub