- Overview
- Architecture
- Directory Structure
- Environment Configuration
- Docker Compose Setup
- Database Schema
- Scripts Documentation
- ProxySQL Configuration
- Replication Setup Process
- Elasticsearch Setup
- Monitoring and Maintenance
- Troubleshooting
- Best Practices
This is a comprehensive Database and Search System, a containerized solution designed for high availability, read scalability, and fast search operations. It implements:
- MySQL Master-Slave Replication with ProxySQL for query routing
- Elasticsearch for full-text search on artist data
- Kibana for search visualization and management
Specifically optimized for user management and content discovery operations.
- Master-Slave Replication: 1 primary (master) + 3 replicas (slaves) per database
- GTID-based Replication: Global Transaction Identifiers for consistent replication
- ProxySQL Load Balancing: Automatic read/write query routing
- Elasticsearch Search: Fast artist search with autocomplete
- Automated Setup: One-click deployment and configuration
- Health Monitoring: Built-in replication and search status checking
- Docker Containerization: Consistent deployment across environments
- Database management systems requiring high read throughput.
- Applications needing database high availability.
- Systems requiring separation of read and write operations.
- Music/content platforms requiring fast artist search and filtering.
- Development environments mimicking production setups.
┌─────────────────┐ ┌──────────────────┐
│ Application │───>│ ProxySQL │
└─────────────────┘ └──────────────────┘
│
┌─────────┼───────────────────┐
│ │ │ │
┌─────▼───┐ ┌───▼───┐ ┌───▼───┐ ┌───▼───┐
│Primary │ │Replica│ │Replica│ │Replica│
│(Master) │ │ 1 │ │ 2 │ │ 3 │
│Port:1000│ │:1001 │ │:1002 │ │:1003 │
└─────────┘ └───────┘ └───────┘ └───────┘
│ ▲ ▲ ▲
└─────────┴─────────┴─────────┘
GTID Replication
┌─────────────────────────────────────────────────────────────┐
│ Search Layer │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌────────┐ │
│ │ Kibana │ │ Elasticsearch│ │Python │ │
│ │ (Port:1201)│<───────>│ (Port:1200) │<───────│Setup │ │
│ │ Dashboard │ │ Search Index│ │Import │ │
│ └─────────────┘ └─────────────┘ └────────┘ │
│ ▲ │
│ │ (MySQL via ProxySQL) │
│ ┌────┴────┐ │
│ │ ProxySQL│ │
│ │ Content │ │
│ │ (Port:1036) │
│ └─────────┘ │
└─────────────────────────────────────────────────────────────┘
- Primary (Master): Handles all write operations, source of truth
- Replicas (Slaves): Handle read operations, maintain synchronized copies
- ProxySQL: Routes queries based on type:-
- INSERT/UPDATE/DELETE → primary
- SELECT → replicas
- Elasticsearch: Full-text search engine for artist data
- Stores denormalized artist + country data
- Provides fast autocomplete and filtering
- Accessible on port 1200
- Kibana: Visualization and management UI for Elasticsearch
- Query and inspect search data
- Accessible on port 1201
- Python Setup: One-time data import from MySQL to Elasticsearch
- Runs automatically after database setup
- Creates index mappings and imports ~37K artists
D:\KYOKU\KYOKU-DOCKER/
├── .env.example # Template for environment setup
├── .gitignore # Git ignore rules
├── docker-compose.yml # Docker services definition
├── run.bat # Main setup and execution script
├── readme.md # This documentation
├── data/ # Persistent data storage
│ ├── mysql/ # MySQL data files
│ └── redis/ # Redis data files
├── mysql/ # MySQL configuration
│ ├── content/ # Content database (artists, songs)
│ │ ├── proxy/
│ │ ├── scripts/
│ │ └── sql/
│ ├── playlist/
│ ├── user/
│ └── activity/
├── nosql/ # MongoDB configuration
├── python-setup/ # NEW: Elasticsearch data import
│ ├── Dockerfile # Python container definition
│ ├── setup_index.py # Index creation with mappings
│ ├── import_data.py # Bulk data import script
│ ├── requirements.txt # Python dependencies
│ └── README.md # Python setup documentation
└── elastic/ # Elasticsearch data (if persisted)
Remove .example from file .env.example in the root directory.Then add the following variables:
# Root MySQL Passwords
MYSQL_ROOT_USER_PASSWORD=your_strong_root_password
MYSQL_ROOT_PLAYLIST_PASSWORD=your_strong_root_password
MYSQL_ROOT_CONTENT_PASSWORD=your_strong_root_password
MYSQL_ROOT_ACTIVITY_PASSWORD=your_strong_root_password
# Replication User Credentials
MYSQL_USER_REPLICATION_USER=repl_user
MYSQL_USER_REPLICATION_PASSWORD=repl_password
MYSQL_PLAYLIST_REPLICATION_USER=repl_user
MYSQL_PLAYLIST_REPLICATION_PASSWORD=repl_password
MYSQL_CONTENT_REPLICATION_USER=repl_user
MYSQL_CONTENT_REPLICATION_PASSWORD=repl_password
MYSQL_ACTIVITY_REPLICATION_USER=repl_user
MYSQL_ACTIVITY_REPLICATION_PASSWORD=repl_password# Elasticsearch
ELASTIC_ROOT_PASSWORD=your_elastic_passwordPurpose: Superuser password for Elasticsearch authentication.
Usage:
- Access Elasticsearch API:
http://elastic:password@localhost:1200 - Login to Kibana:
elastic/password
Security Note: Use a strong password. Elasticsearch has security enabled by default.
- Use strong passwords for all accounts
- Consider using Docker secrets in production
- Rotate passwords regularly
- Limit network access to necessary ports only
user-primary:
image: mysql:8.4.0
container_name: user-primary
ports:
- "1000:3306"
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_USER_PASSWORD}
MYSQL_REPLICATION_USER: ${MYSQL_USER_REPLICATION_USER}
MYSQL_REPLICATION_PASSWORD: ${MYSQL_USER_REPLICATION_PASSWORD}
command: >
--server-id=1
--log-bin=mysql-bin
--binlog-do-db=USER
--gtid-mode=ON
--enforce-gtid-consistency=ON
--log-replica-updates=ON
--binlog-expire-logs-seconds=604800Configuration Explained:
server-id=1: Unique identifier for the primary serverlog-bin=mysql-bin: Enables binary logging for replicationbinlog-do-db=USER: Only replicate the USER databasegtid-mode=ON: Enables Global Transaction Identifiersenforce-gtid-consistency=ON: Ensures GTID safetylog-replica-updates=ON: Logs updates from replicasbinlog-expire-logs-seconds=604800: Keeps binary logs for 7 days
user-replica1:
image: mysql:8.4.0
container_name: user-replica1
ports:
- "1001:3306"
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_USER_PASSWORD}
command: >
--server-id=2
--relay-log=relay-bin
--read-only=1
--gtid-mode=ON
--enforce-gtid-consistency=ON
--log-replica-updates=ON
--skip-replica-start=1Configuration Explained:
server-id=2/3/4: Unique identifiers for each replicarelay-log=relay-bin: Enables relay loggingread-only=1: Prevents writes on replicasskip-replica-start=1: Prevents automatic replication start
- SQL initialization files are mounted to
/docker-entrypoint-initdb.d/ - Data directories are persisted to
./data/mysql/data/[service-name]/data
CREATE TABLE UserType
(
id INT PRIMARY KEY AUTO_INCREMENT,
`type` VARCHAR(8) NOT NULL UNIQUE
);Purpose: Stores user authentication types (GOOGLE, EMAIL)
Key Features:
- Short VARCHAR to optimize storage
- Unique constraint prevents duplicates
CREATE TABLE Country
(
id INT PRIMARY KEY AUTO_INCREMENT,
country VARCHAR(40) NOT NULL,
code VARCHAR(4) NOT NULL,
UNIQUE KEY uq_country (country),
UNIQUE KEY uq_code (code)
);Purpose: Reference table for country data.
Key Features:
- Dual unique constraints on country name and code
- Normalized design reduces data redundancy
CREATE TABLE `User`
(
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_type_id INT NOT NULL,
email VARCHAR(320) NOT NULL,
username VARCHAR(320) NOT NULL,
display_name VARCHAR(320) NOT NULL,
password_hash VARCHAR(700) NOT NULL,
profile_pic VARCHAR(700) DEFAULT NULL,
birth_date DATE DEFAULT NULL,
country_id INT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-- Constraints and Indexes
UNIQUE KEY uq_user_type_email (user_type_id, email),
INDEX idx_email (email),
INDEX idx_user_type_id (user_type_id),
CONSTRAINT fk_user_user_type FOREIGN KEY (user_type_id) REFERENCES UserType (id),
CONSTRAINT fk_user_country FOREIGN KEY (country_id) REFERENCES Country (id)
);Design Decisions Explained:
BIGINTfor ID: Accommodates large user basesVARCHAR(320)for email: Supports maximum RFC-compliant email lengthVARCHAR(700)for password_hash: Accommodates various hashing algorithms- Composite unique key: Prevents duplicate emails per user type
- Foreign key constraints: Ensures referential integrity
- Timestamps: Automatic tracking of creation and modification
CREATE TABLE UserJWTToken
(
user_id BIGINT PRIMARY KEY,
refresh_token VARCHAR(1000) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_user_token FOREIGN KEY (user_id) REFERENCES `User` (id) ON DELETE CASCADE
);Purpose: Stores JWT refresh tokens.
Key Features:
- One-to-one relationship with User
- Cascade delete ensures cleanup
- Large VARCHAR accommodates JWT tokens
Purpose: Primary script that orchestrates the entire setup process including databases and search
Execution Flow:
- Docker Validation: Verifies Docker is running
- Configuration Generation: Calls
generate-configs.batfor all databases - Service Startup: Executes
docker-compose up -d - Initialization Wait: 30-second delay for service initialization
- Replication Setup: Calls
start-replication.batfor MySQL databases - Elasticsearch Setup:
- Waits for Elasticsearch and MySQL ProxySQL to be healthy
- Builds Python setup image
- Creates
artistsindex with mappings - Imports ~37K artists from MySQL to Elasticsearch
- Verifies document count
Error Handling:
- Exits on Docker unavailability
- Validates each step before proceeding
- Provides clear error messages
- Elasticsearch setup failures are reported but don't block MySQL setup
Usage:
run.batPurpose: Generates configuration files from templates using environment variables
Process:
- Loads environment variables from
.env - Validates template file existence
- Uses PowerShell string replacement to generate:
proxysql.conffromproxysql.conf.templatesetup-replication-master.sqlfromsetup-replication-master.sql.template
Template Placeholders:
{{MYSQL_USER_PROXY_ADMIN}}→ ProxySQL admin username{{MYSQL_USER_PROXY_PASSWORD}}→ ProxySQL admin password{{MYSQL_USER_USER}}→ Application user{{MYSQL_USER_PASSWORD}}→ Application password{{MYSQL_USER_REPLICATION_USER}}→ Replication user{{MYSQL_USER_REPLICATION_PASSWORD}}→ Replication password{{MYSQL_MONITOR_USER}}→ Monitor user{{MYSQL_MONITOR_PASSWORD}}→ Monitor password
Purpose: Configures master-slave replication across all MySQL instances
Detailed Process:
- Environment Loading: Reads credentials from
.env - Connection Testing: Verifies primary database accessibility
- User Verification: Ensures replication user exists
- GTID Verification: Confirms GTID mode is enabled
- Replica Configuration: For each replica:
- Tests connectivity
- Stops existing replication
- Resets replication configuration
- Configures replication source using MySQL 8.x syntax
- Starts replication
- Status Verification: Checks replication status
MySQL 8.x Compatibility:
- Uses
CHANGE REPLICATION SOURCE TOinstead of deprecatedCHANGE MASTER TO - Uses
SHOW REPLICA STATUSinstead ofSHOW SLAVE STATUS - Uses
SHOW BINARY LOG STATUSinstead ofSHOW MASTER STATUS
Error Handling:
- Retries connection attempts (up to 10 times) *
- Displays specific error messages
- Shows replication errors for troubleshooting
Purpose: Provides comprehensive replication health monitoring
Monitoring Areas:
- Master Status: Shows binary log position and file
- Replica Status: For each replica, displays:
Replica_IO_Running: I/O thread statusReplica_SQL_Running: SQL thread statusSeconds_Behind_Source: Replication lagLast_Error: Any replication errors
- ProxySQL Stats: Shows server status in ProxySQL
Output Format:
Master Status
----------------------------------------
File: mysql-bin.000001, Position: 1234
Replica 1 Status
----------------------------------------
Replica_IO_Running: Yes
Replica_SQL_Running: Yes
Seconds_Behind_Source: 0
Last_Error: (empty if no errors)
Purpose: Validates replication functionality through data insertion and verification
Test Process:
- Test Data Generation: Creates unique test value with timestamp
- Primary Insertion: Inserts test data into the UserType table on primary
- Replication Wait: 3-second delay for replication propagation
- Replica Verification: Checks each replica for test data presence
- Cleanup: Removes test data from primary (propagates to replicas)
Test Data Structure:
INSERT INTO UserType (type)
VALUES ('test');Success Indicators:
- Test data appears on all replicas
- No replication errors reported
- Cleanup successful
admin_variables = {
admin_credentials = "{{MYSQL_USER_PROXY_ADMIN}}:{{MYSQL_USER_PROXY_PASSWORD}}"
mysql_ifaces = "0.0.0.0:6032"
}Purpose: Administrative access configuration Access: Port 6032 for ProxySQL administration
mysql_variables = {
threads = 4
max_connections = 2048
default_query_delay = 0
default_query_timeout = 36000000
interfaces = "0.0.0.0:6033"
default_schema = "information_schema"
monitor_username = "{{MYSQL_USER_MONITOR_USER}}"
monitor_password = "{{MYSQL_USER_MONITOR_PASSWORD}}"
monitor_history = 600000
monitor_connect_interval = 60000
monitor_ping_interval = 10000
}Key Settings Explained:
threads=4: Number of worker threadsmax_connections=2048: Maximum concurrent connectionsdefault_query_timeout=36000000: 10-hour query timeoutinterfaces="0.0.0.0:6033": MySQL protocol interfacemonitor_*: Health monitoring configuration
mysql_servers = (
{
address="user-primary"
port=3306
hostgroup=0
weight=1000
comment="Primary Server"
},
{
address="user-replica1"
port=3306
hostgroup=1
weight=900
comment="Read Replica 1"
}
# ... additional replicas
)
Hostgroup Strategy:
- Hostgroup 0: Write operations (primary only)
- Hostgroup 1: Read operations (all replicas)
- Weight 900: Load balancing priority (all replicas have the same priority)
mysql_query_rules
= (
{
rule_id=1
active=1
match_pattern="^SELECT.*"
destination_hostgroup=1
apply=1
comment="Route SELECT to read replicas"
},
{
rule_id=2
active=1
match_pattern="^INSERT|UPDATE|DELETE.*"
destination_hostgroup=0
apply=1
comment="Route writes to primary"
}
)
Routing Logic:
- SELECT queries: Automatically routed to read replicas (hostgroup 1)
- INSERT/UPDATE/DELETE: Routed to primary (hostgroup 0)
- Pattern matching: Uses regex for query type detection
- Environment variable validation
- Docker service availability check
- Configuration file generation from templates
- Docker Compose service startup
- Wait for primary database initialization
- Verify replication user creation
- Confirm GTID mode activation
- Validate binary logging configuration
For each replica server:
- Connection Testing: Verify replica accessibility
- GTID Validation: Ensure GTID mode compatibility
- Replication Reset: Clear any existing replication configuration
- Source Configuration: Set primary as replication source
- Authentication Setup: Configure replication user credentials
- Auto-positioning: Enable GTID-based positioning
- SSL Configuration: Set up secure connections
- Replication Start: Initiate replication process
- Status Verification: Check replication thread status
- Lag Monitoring: Verify replication lag is minimal
- Error Detection: Identify and report any issues
- Functional Testing: Validate data replication through test insertions
Elasticsearch provides full-text search capabilities for artist data, enabling fast search by name and filtering by country code.
MySQL (CONTENT DB)
↓ (via ProxySQL)
Python Setup Script
↓ (HTTP Bulk API)
Elasticsearch ← Kibana (UI)
↓
Search Service (future)
| Component | Port | Purpose |
|---|---|---|
| Elasticsearch | 1200 | Search engine API |
| Kibana | 1201 | Visualization and management UI |
| Python Setup | - | One-time data import |
The Elasticsearch setup runs automatically as Step 5 in run.bat, after all MySQL databases are configured:
- Wait for Elasticsearch - Health check until ready
- Wait for MySQL ProxySQL - Ensure content database is accessible
- Build Python Image - Container with elasticsearch and mysql-connector packages
- Create Index - Setup index with custom analyzer for artist name search
- Import Data - Bulk import ~37K artists from MySQL to Elasticsearch
- Verify Import - Check document count matches expected
If you need to run Elasticsearch setup separately:
# Start infrastructure only
docker-compose up -d elasticsearch kibana content-proxysql
# Wait for services to be healthy
# Then run setup
docker-compose --profile setup run --rm python-setupThe artists index is configured with:
| Field | Type | Description |
|---|---|---|
id |
keyword | Artist ID from MySQL |
name |
text + keyword | Artist name with edge n-gram analyzer for autocomplete |
coverImage |
keyword | Artist cover image URL (not indexed) |
followers |
long | Follower count for popularity sorting |
countryCodes |
keyword[] | Array of country codes (e.g., ["IN", "US"]) |
countryNames |
text[] | Array of country names |
Creates edge n-grams (2-20 characters) for prefix matching:
- Input: "Eminem"
- Tokens: ["Em", "Emi", "Emin", "Eminem"]
- Use Case: Search "Emin" → finds "Eminem"
Via HTTP API:
# Check cluster health
curl -u elastic:$ELASTIC_ROOT_PASSWORD http://localhost:1200/_cluster/health
# Search artists
curl -u elastic:$ELASTIC_ROOT_PASSWORD http://localhost:1200/artists/_search?q=name:Eminem
# Get document count
curl -u elastic:$ELASTIC_ROOT_PASSWORD http://localhost:1200/artists/_countVia Kibana:
- Open http://localhost:1201
- Login:
elastic/$ELASTIC_ROOT_PASSWORD - Navigate to Dev Tools
- Run queries in the console
To force a re-import (deletes and recreates index):
# Delete existing index
curl -X DELETE -u elastic:$ELASTIC_ROOT_PASSWORD http://localhost:1200/artists
# Re-run setup
docker-compose --profile setup run --rm python-setupOr simply run run.bat again - it will detect missing/partial data and re-import automatically.
| Issue | Solution |
|---|---|
| Import fails with connection error | Check Elasticsearch health: docker-compose ps |
| MySQL connection refused | Verify ProxySQL is running on port 1036 |
| Document count is 0 | Check Python setup logs: docker-compose logs python-setup |
| Kibana can't connect to ES | Verify ES is healthy before starting Kibana |
- Replica_IO_Running: Should always be "Yes"
- Replica_SQL_Running: Should always be "Yes"
- Seconds_Behind_Source: Should be < 5 seconds under normal load
- Last_Error: Should be empty
- Connection Count: Monitor concurrent connections
- Query Distribution: Verify read/write query routing
- Server Status: Ensure all servers are "ONLINE"
# Check replication status
mysql\user\scripts\check-replication.bat
# Test replication functionality
mysql\user\scripts\test-replication.bat
SHOW BINARY LOG STATUS;
SHOW VARIABLES LIKE 'gtid%';
SELECT COUNT(*)
FROM information_schema.processlist
WHERE command = 'Binlog Dump GTID';SHOW
REPLICA STATUS
\G
SELECT @@read_only;
SHOW
VARIABLES LIKE 'gtid%';-- Connect to ProxySQL admin interface (port 6032)
SELECT hostgroup_id, hostname, port, status, weight
FROM mysql_servers;
SELECT rule_id, match_pattern, destination_hostgroup
FROM mysql_query_rules
WHERE active = 1;- Check replication lag
- Monitor error logs
- Verify backup completion
- Review query performance
- Rotate binary logs
- Update ProxySQL statistics
- Review capacity metrics
- Test failover procedures
- Security audit (password rotation)
- Performance optimization
- Disaster recovery testing
- Documentation updates
Symptoms:
- Replica_IO_Running: No
- Last_IO_Error: Connection refused
Solutions:
-
Check Network Connectivity:
docker exec user-replica1 ping user-primary -
Verify Credentials:
-- On primary SELECT User, Host FROM mysql.user WHERE User = 'repl_user';
-
Reset Replication:
mysql\user\scripts\start-replication.bat
Symptoms:
- Seconds_Behind_Source > 30
- Slow query performance on replicas
Solutions:
-
Check Primary Load:
SHOW PROCESSLIST; SHOW ENGINE INNODB STATUS;
-
Optimize Replica Performance:
-- Increase parallel workers SET GLOBAL replica_parallel_workers = 4;
-
Review Binary Log Size:
SHOW VARIABLES LIKE 'max_binlog_size';
Symptoms:
- Application unable to connect
- "Host 'X' is not allowed to connect" errors
Solutions:
-
Check User Privileges:
-- On primary SHOW GRANTS FOR 'app_user'@'%';
-
Verify ProxySQL Configuration:
-- Connect to ProxySQL admin SELECT * FROM mysql_users; SELECT * FROM mysql_servers;
-
Restart ProxySQL:
docker-compose restart user-proxysql
Symptoms:
- "Statement violates GTID consistency"
- Replication stops with GTID errors
Solutions:
-
Check GTID Mode:
SHOW VARIABLES LIKE 'gtid_mode'; SHOW VARIABLES LIKE 'enforce_gtid_consistency';
-
Skip Problematic Transaction (Use with caution):
STOP REPLICA; SET GTID_NEXT='UUID:NUMBER'; BEGIN; COMMIT; SET GTID_NEXT='AUTOMATIC'; START REPLICA;
# Container logs
docker logs user-primary
# MySQL error logs (inside container)
/var/log/mysql/error.log
# Binary log information
SHOW BINARY LOGS;-- Check specific error details
SHOW
REPLICA STATUS
\G
-- Look for common issues
grep -i "error\|warn\|fail" /var/log/mysql/error.log-- Reduce binary log retention
SET
GLOBAL binlog_expire_logs_seconds = 259200;
-- 3 days
-- Optimize binary log format
SET
GLOBAL binlog_format = 'ROW';-- Parallel replication
SET
GLOBAL replica_parallel_type = 'LOGICAL_CLOCK';
SET
GLOBAL replica_parallel_workers = 4;
-- Skip slave errors (development only)
SET
GLOBAL sql_replica_skip_counter = 1;- Use strong, unique passwords for each service
- Rotate passwords regularly (quarterly recommended)
- Store passwords securely (consider Docker secrets)
- Limit password exposure in logs and configuration files
# Example secure network configuration
networks:
db-network:
driver: bridge
internal: true # Prevents external access-- Principle of least privilege
CREATE
USER 'app_read_only'@'%' IDENTIFIED BY 'password';
GRANT
SELECT
ON USER.* TO 'app_read_only'@'%';
-- Regular privilege audits
SELECT User, Host, authentication_string
FROM mysql.user;-- InnoDB optimization
SET
GLOBAL innodb_buffer_pool_size = '1G';
SET
GLOBAL innodb_log_file_size = '256M';
SET
GLOBAL innodb_flush_log_at_trx_commit = 2;
-- Query cache (if applicable)
SET
GLOBAL query_cache_size = 67108864;
SET
GLOBAL query_cache_type = ON;// Connection pooling
mysql_variables = {
max_connections = 2048
default_max_latency_ms = 1000
threshold_query_length = 524288
threshold_resultset_size = 4194304
}# Set up monitoring scripts
#!/bin/bash
# Check replication lag every minute
REPLICATION_LAG=$(mysql -h replica1 -e "SHOW REPLICA STATUS\G" | grep "Seconds_Behind_Source" | awk '{print $2}')
if [ "$REPLICATION_LAG" -gt 30 ]; then
echo "ALERT: High replication lag: $REPLICATION_LAG seconds" | mail -s "MySQL Alert" admin@company.com
fi# Full backup script
#!/bin/bash
BACKUP_DIR="/backup/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
# Primary backup
docker exec user-primary mysqldump --single-transaction --routines --triggers --all-databases > "$BACKUP_DIR/primary_$DATE.sql"
# Binary log backup
docker exec user-primary mysql -e "FLUSH LOGS;"
docker cp user-primary:/var/lib/mysql/mysql-bin.* "$BACKUP_DIR/"# Point-in-time recovery
mysql < full_backup.sql
mysqlbinlog --start-datetime="2024-01-01 12:00:00" --stop-datetime="2024-01-01 12:30:00" mysql-bin.000001 | mysql# Reduced resource allocation
environment:
- MYSQL_ROOT_PASSWORD=dev_password
command: >
--server-id=1
--log-bin=mysql-bin
--binlog-expire-logs-seconds=86400 # 1 day
--innodb-buffer-pool-size=128M # Smaller buffer# Production optimizations
environment:
- MYSQL_ROOT_PASSWORD=${SECURE_ROOT_PASSWORD}
command: >
--server-id=1
--log-bin=mysql-bin
--binlog-expire-logs-seconds=604800 # 7 days
--innodb-buffer-pool-size=2G # Larger buffer
--innodb-log-file-size=512M
--max-connections=1000- Read Scaling: Add more replicas as read load increases
- Write Scaling: Consider sharding or write scaling solutions
- Storage Growth: Monitor and plan for data growth
- Connection Scaling: Tune ProxySQL connection pooling
-- Monitor key metrics
SELECT VARIABLE_NAME,
VARIABLE_VALUE
FROM performance_schema.global_status
WHERE VARIABLE_NAME IN (
'Connections',
'Queries',
'Slow_queries',
'Bytes_sent',
'Bytes_received'
);This documentation provides a comprehensive guide to understanding, deploying, and maintaining the KYOKU MySQL Replication System. Regular updates to this documentation should be made as the system evolves and new requirements emerge.