mysql
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseMySQL / MariaDB
MySQL / MariaDB
Administer, optimize, and secure MySQL and MariaDB databases in development and production environments.
在开发和生产环境中管理、优化并保障MySQL和MariaDB数据库的安全。
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.
- 你需要一个成熟、被广泛支持的关系型数据库。
- 你的技术栈依赖MySQL特定功能或兼容性(如WordPress、Magento、众多PHP框架)。
- 你正在搭建源-副本复制以实现读取扩展。
- 你希望针对高吞吐量事务工作负载调优InnoDB。
Prerequisites
前置条件
- Linux server (Debian/Ubuntu or RHEL-based) or Docker.
- Root or sudo access for package installation.
- Familiarity with SQL fundamentals.
- Linux服务器(Debian/Ubuntu或基于RHEL的系统)或Docker环境。
- 具备Root或sudo权限以安装软件包。
- 熟悉SQL基础知识。
Installation and Setup
安装与配置
bash
undefinedbash
undefinedDebian / Ubuntu — MySQL 8
Debian / Ubuntu — MySQL 8
sudo apt update
sudo apt install -y mysql-server
sudo apt update
sudo apt install -y mysql-server
RHEL / Amazon Linux
RHEL / Amazon Linux
sudo dnf install -y mysql-server
sudo systemctl enable --now mysqld
sudo dnf install -y mysql-server
sudo systemctl enable --now mysqld
Run the secure installation wizard
Run the secure installation wizard
sudo mysql_secure_installation
sudo mysql_secure_installation
Prompts: set root password, remove anonymous users, disable remote root, remove test db
Prompts: set root password, remove anonymous users, disable remote root, remove test db
Verify
Verify
mysql --version
sudo systemctl status mysql
undefinedmysql --version
sudo systemctl status mysql
undefinedInitial User and Database Setup
初始用户与数据库配置
bash
sudo mysql -u root -psql
-- 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'@'%';bash
sudo mysql -u root -psql
-- 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
mysql命令行参考
bash
undefinedbash
undefinedConnect
Connect
mysql -u myapp -p -h 127.0.0.1 mydb
mysql -u myapp -p -h 127.0.0.1 mydb
Execute a single statement
Execute a single statement
mysql -u myapp -p -e "SELECT COUNT(*) FROM orders;" mydb
mysql -u myapp -p -e "SELECT COUNT(*) FROM orders;" mydb
Import a SQL file
Import a SQL file
mysql -u myapp -p mydb < schema.sql
mysql -u myapp -p mydb < schema.sql
Export query results to CSV
Export query results to CSV
mysql -u myapp -p -e "SELECT * FROM users" mydb
| tr '\t' ',' > users.csv
| tr '\t' ',' > users.csv
undefined-- Inside the mysql shell
SHOW DATABASES;
USE mydb;
SHOW TABLES;
DESCRIBE users;
SHOW CREATE TABLE users\G
SHOW PROCESSLIST;
SHOW ENGINE INNODB STATUS\G
undefinedmysql -u myapp -p -e "SELECT * FROM users" mydb
| tr '\t' ',' > users.csv
| tr '\t' ',' > users.csv
undefined-- Inside the mysql shell
SHOW DATABASES;
USE mydb;
SHOW TABLES;
DESCRIBE users;
SHOW CREATE TABLE users\G
SHOW PROCESSLIST;
SHOW ENGINE INNODB STATUS\G
undefinedConfiguration Tuning
配置调优
Edit (or on RHEL).
/etc/mysql/mysql.conf.d/mysqld.cnf/etc/my.cnfini
[mysqld]编辑(RHEL系统为)。
/etc/mysql/mysql.conf.d/mysqld.cnf/etc/my.cnfini
[mysqld]-- Networking --
-- Networking --
bind-address = 0.0.0.0
max_connections = 300
wait_timeout = 600
interactive_timeout = 600
bind-address = 0.0.0.0
max_connections = 300
wait_timeout = 600
interactive_timeout = 600
-- InnoDB (most impactful settings) --
-- 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
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 (disabled in MySQL 8, use ProxySQL or app cache) --
query_cache_type = 0
query_cache_type = 0
-- Logging --
-- 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
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) --
-- 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
server-id = 1
log_bin = /var/log/mysql/mysql-bin
binlog_expire_logs_seconds = 604800 # 7 days
sync_binlog = 1
-- Character set --
-- Character set --
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
```bashcharacter-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
```bashApply changes
Apply changes
sudo systemctl restart mysql
sudo systemctl restart mysql
Verify a setting at runtime
Verify a setting at runtime
mysql -u root -p -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
undefinedmysql -u root -p -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
undefinedBackup and Restore
备份与恢复
Logical Backups with mysqldump
使用mysqldump进行逻辑备份
bash
undefinedbash
undefinedSingle database
Single database
mysqldump -u root -p --single-transaction --routines --triggers
mydb > /backups/mydb_$(date +%F).sql
mydb > /backups/mydb_$(date +%F).sql
mysqldump -u root -p --single-transaction --routines --triggers
mydb > /backups/mydb_$(date +%F).sql
mydb > /backups/mydb_$(date +%F).sql
All databases
All databases
mysqldump -u root -p --all-databases --single-transaction \
/backups/all_$(date +%F).sql
mysqldump -u root -p --all-databases --single-transaction \
/backups/all_$(date +%F).sql
Compressed backup
Compressed backup
mysqldump -u root -p --single-transaction mydb
| gzip > /backups/mydb_$(date +%F).sql.gz
| gzip > /backups/mydb_$(date +%F).sql.gz
mysqldump -u root -p --single-transaction mydb
| gzip > /backups/mydb_$(date +%F).sql.gz
| gzip > /backups/mydb_$(date +%F).sql.gz
Restore
Restore
mysql -u root -p mydb < /backups/mydb_2025-01-15.sql
mysql -u root -p mydb < /backups/mydb_2025-01-15.sql
Restore compressed
Restore compressed
gunzip < /backups/mydb_2025-01-15.sql.gz | mysql -u root -p mydb
undefinedgunzip < /backups/mydb_2025-01-15.sql.gz | mysql -u root -p mydb
undefinedPhysical Backups with Percona XtraBackup
使用Percona XtraBackup进行物理备份
bash
undefinedbash
undefinedInstall
Install
sudo apt install -y percona-xtrabackup-80
sudo apt install -y percona-xtrabackup-80
Full backup
Full backup
xtrabackup --backup --user=root --password=secret
--target-dir=/backups/full_$(date +%F)
--target-dir=/backups/full_$(date +%F)
xtrabackup --backup --user=root --password=secret
--target-dir=/backups/full_$(date +%F)
--target-dir=/backups/full_$(date +%F)
Prepare the backup (apply redo logs)
Prepare the backup (apply redo logs)
xtrabackup --prepare --target-dir=/backups/full_2025-01-15
xtrabackup --prepare --target-dir=/backups/full_2025-01-15
Restore (stop MySQL first)
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
undefinedsudo 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
undefinedIncremental Backup with XtraBackup
使用XtraBackup进行增量备份
bash
undefinedbash
undefinedIncremental based on the full backup
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
--target-dir=/backups/inc_$(date +%F)
--incremental-basedir=/backups/full_2025-01-15
xtrabackup --backup --user=root --password=secret
--target-dir=/backups/inc_$(date +%F)
--incremental-basedir=/backups/full_2025-01-15
--target-dir=/backups/inc_$(date +%F)
--incremental-basedir=/backups/full_2025-01-15
Prepare: apply full, then incremental
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
--incremental-dir=/backups/inc_2025-01-16
undefinedxtrabackup --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
--incremental-dir=/backups/inc_2025-01-16
undefinedSource-Replica Replication
源-副本复制
Source (Primary)
源服务器(主节点)
ini
undefinedini
undefined/etc/mysql/mysql.conf.d/mysqld.cnf
/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[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\GReplica
副本服务器
ini
undefinedini
undefined/etc/mysql/mysql.conf.d/mysqld.cnf
/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[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 = 0Monitoring 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_Sourcesql
-- 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_SourceDocker Compose Setup
Docker Compose部署
yaml
undefinedyaml
undefineddocker-compose.yml
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 mydbversion: "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 mydbMaintenance Tasks
维护任务
bash
undefinedbash
undefinedOptimize a fragmented table (locks the table briefly)
Optimize a fragmented table (locks the table briefly)
mysql -u root -p -e "OPTIMIZE TABLE mydb.orders;"
mysql -u root -p -e "OPTIMIZE TABLE mydb.orders;"
Analyze tables to update statistics
Analyze tables to update statistics
mysql -u root -p -e "ANALYZE TABLE mydb.orders;"
mysql -u root -p -e "ANALYZE TABLE mydb.orders;"
Check and repair a table
Check and repair a table
mysql -u root -p -e "CHECK TABLE mydb.orders;"
mysql -u root -p -e "REPAIR TABLE mydb.orders;"
mysql -u root -p -e "CHECK TABLE mydb.orders;"
mysql -u root -p -e "REPAIR TABLE mydb.orders;"
Rotate slow query log
Rotate slow query log
sudo mv /var/log/mysql/slow.log /var/log/mysql/slow.log.old
mysqladmin -u root -p flush-logs
undefinedsudo mv /var/log/mysql/slow.log /var/log/mysql/slow.log.old
mysqladmin -u root -p flush-logs
undefinedTroubleshooting
故障排查
| Symptom | Likely Cause | Fix |
|---|---|---|
| Connection limit exceeded | Increase |
| Slow queries across the board | | Set to ~70% of available RAM and restart |
Replication stopped ( | Duplicate key or schema mismatch on replica | Check |
| Disk space exhausted or table limit hit | Free disk space; check |
| Long-running transaction holding row locks | Identify with |
| High IOPS / disk usage | Redo log too small causing frequent flushes | Increase |
| 症状 | 可能原因 | 解决方法 |
|---|---|---|
| 连接数超出限制 | 增大 |
| 全系统查询缓慢 | | 将其设置为可用内存的~70%并重启服务 |
复制停止( | 副本服务器存在重复键或 schema 不匹配 | 查看 |
| 磁盘空间耗尽或达到表限制 | 释放磁盘空间;检查 |
| 长时间运行的事务持有行锁 | 通过 |
| 高IOPS/磁盘占用 | 重做日志过小导致频繁刷盘 | 增大 |
Related Skills
相关技能
- postgresql - Alternative relational database
- database-backups - Automated backup strategies
- redis - Caching layer to reduce database load
- planetscale - Managed MySQL-compatible with branching
- postgresql - 替代关系型数据库
- database-backups - 自动化备份策略
- redis - 缓存层以降低数据库负载
- planetscale - 支持分支功能的托管式MySQL兼容服务