Database Dokumentation - CBZHotels

Forside

Underskrifter:

Indholdsfortegnelse

  1. Opgavebeskrivelse
  2. Problemformulering
  3. Løsningsforslag
  4. Netværkstopologi
  5. UML Diagrammer
  6. Overordnet Designbeskrivelse
  7. Teoriafsnit
  8. Server Dokumentation
  9. Login Oplysninger
  10. Arbejdsfordeling
  11. Diskussion
  12. Konklusion
  13. Kilder og Referencer
  14. Bilag

Opgavebeskrivelse

CBZHotels er en hotelkæde bestående af 5 hoteller, der har brug for et centralt database system til at håndtere bookinger, gæster, værelser og personale. Systemet skal også kunne håndtere konferencefaciliteter og særlige arrangementer.

Problemformulering

Kundens Ønsker og Udfordringer

  1. Centraliseret Hotelstyring

    • Hvordan kan vi designe en database der effektivt håndterer 5 forskellige hoteller under samme system?
    • Hvordan sikrer vi at hvert hotel kan operere uafhængigt men stadig dele central data?
  2. Booking og Rabatsystem

    • Hvordan implementerer vi et fleksibelt bookingsystem der kan håndtere:
      • Online bookinger med 10% rabat
      • FDM medlemsrabat på 12%
      • Forskellige værelsestyper og priser
      • Særlige gæstebehov (kørestol, førerhund, etc.)
  3. Personalestyring

    • Hvordan håndterer vi de forskellige personaletyper effektivt:
      • 3 stuepiger/rengøringsmedhjælpere pr. hotel
      • 2 ledere pr. hotel
      • 8 administrations/receptionspersonale pr. hotel
      • 8 betjeningspersonale/køkkenpersonale pr. hotel
  4. Konferencefaciliteter

    • Hvordan integrerer vi konferencebooking funktionalitet specifikt for "The Pope" hotel?
    • Hvordan håndterer vi specielle arrangementer som Pave Francis' besøg?

Løsningsforslag

Database Arkitektur

  1. Centraliseret Database Struktur

    • Implementeret i MariaDB 11.1.2
    • Centralt administrationssystem med distribueret adgang
    • Separate schemas for hver hovedfunktion (booking, personale, konference)
  2. Booking System

    CREATE TABLE Bookinger ( booking_id INT PRIMARY KEY, gæst_id INT, værelse_id INT, check_ind_dato DATE, check_ud_dato DATE, online_booking BOOLEAN, fdm_medlem BOOLEAN, FOREIGN KEY (gæst_id) REFERENCES Gæster(gæst_id), FOREIGN KEY (værelse_id) REFERENCES Værelser(værelse_id) ); -- Rabat håndtering CREATE TRIGGER beregn_rabat BEFORE INSERT ON Bookinger FOR EACH ROW BEGIN SET NEW.total_pris = CASE WHEN NEW.fdm_medlem THEN NEW.basis_pris * 0.88 WHEN NEW.online_booking THEN NEW.basis_pris * 0.90 ELSE NEW.basis_pris END; END;
  3. Personale Management

    • Implementeret rollebaseret system med:
      CREATE TABLE Personale ( personale_id INT PRIMARY KEY, hotel_id INT, rolle_id INT, navn VARCHAR(100), ansættelses_dato DATE, FOREIGN KEY (hotel_id) REFERENCES Hoteller(hotel_id), FOREIGN KEY (rolle_id) REFERENCES Personale_Roller(rolle_id) ); -- Rolle begrænsninger CREATE TRIGGER check_personale_antal BEFORE INSERT ON Personale FOR EACH ROW BEGIN DECLARE antal INT; SELECT COUNT(*) INTO antal FROM Personale WHERE hotel_id = NEW.hotel_id AND rolle_id = NEW.rolle_id; IF (NEW.rolle_id = 1 AND antal >= 3) THEN -- Stuepiger SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Maksimum antal stuepiger nået for dette hotel'; END IF; -- Lignende checks for andre roller END;
  4. Konference System

    • Specialdesignet modul for "The Pope" hotel:
      CREATE TABLE Konference_Bookinger ( konference_id INT PRIMARY KEY, hotel_id INT, antal_deltagere INT, start_dato DATETIME, slut_dato DATETIME, udstyr_behov TEXT, forplejning TEXT, special_ønsker TEXT, CONSTRAINT chk_pope_only CHECK (hotel_id = 1) -- Kun tilladt for "The Pope" hotel );

Implementerede Løsninger

  1. Data Sikkerhed

    • Transaktionsbaseret booking system
    • Daglig backup med point-in-time recovery
    • Krypterede passwords og sensitive data
  2. Performance Optimering

    • Strategisk indeksering af ofte-søgte felter
    • Materialized views for rapportering
    • Query optimization for høj-volumen operationer
  3. Skalerbarhed

    • Designet til at håndtere vækst i antal hoteller
    • Modulær struktur for nem tilføjelse af nye features
    • Load balancing for høj-trafik perioder

Netværkstopologi

Netværkstopologi Figur 1: Netværkstopologi[^1]

UML Diagrammer

ER Diagram

ER Diagram Figur 2: Entity-Relationship Diagram[^2]

Klassediagram

Klassediagram Figur 3: Klassediagram[^3]

Database Diagram

Database Diagram Figur 4: Database Diagram[^4]

Overordnet Designbeskrivelse

Hardware

Software

Netværk

Teoriafsnit

Normalisering

Vi har anvendt følgende normaliseringsregler:

Første Normalform (1NF)

Anden Normalform (2NF)

Tredje Normalform (3NF)

Indeksering Strategi

Transaktionsbaserede Systemer

  1. ACID Principper

    • Atomicity (Atomaritet)

      • Alle operationer i en transaktion udføres, eller ingen af dem
      • Eksempel på booking transaktion:
      START TRANSACTION; -- 1. Check værelse tilgængelighed SELECT @is_available := COUNT(*) FROM Værelser WHERE værelse_id = @værelse_id AND status = 'Ledig'; -- 2. Opdater værelse status UPDATE Værelser SET status = 'Optaget' WHERE værelse_id = @værelse_id; -- 3. Opret booking INSERT INTO Bookinger (gæst_id, værelse_id, ...) VALUES (@gæst_id, @værelse_id, ...); -- Hvis alle operationer lykkedes COMMIT; -- Hvis fejl opstår ROLLBACK;
    • Consistency (Konsistens)

      • Database forbliver i valid tilstand før og efter transaktion
      • Implementeret gennem constraints:
      CREATE TABLE Bookinger ( -- ... andre felter ... CONSTRAINT valid_dates CHECK (check_ud_dato > check_ind_dato), CONSTRAINT valid_room FOREIGN KEY (værelse_id) REFERENCES Værelser(værelse_id) );
    • Isolation (Isolation)

      • Samtidige transaktioner påvirker ikke hinanden
      • Håndteret gennem isolation levels:
      -- Sæt isolation level for kritiske operationer SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; -- Implementer row-level locking SELECT * FROM Værelser WHERE værelse_id = @id FOR UPDATE;
    • Durability (Holdbarhed)

      • Gemte data forbliver gemt selv ved systemfejl
      • Sikret gennem:
      # my.cnf konfiguration innodb_flush_log_at_trx_commit = 1 sync_binlog = 1
  2. Concurrent Booking Håndtering

    CREATE PROCEDURE sp_book_værelse( IN p_gæst_id INT, IN p_værelse_id INT, IN p_check_ind DATE, IN p_check_ud DATE ) BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Booking fejlede'; END; START TRANSACTION; -- Check for overlappende bookinger IF EXISTS ( SELECT 1 FROM Bookinger WHERE værelse_id = p_værelse_id AND ( (check_ind_dato BETWEEN p_check_ind AND p_check_ud) OR (check_ud_dato BETWEEN p_check_ind AND p_check_ud) ) ) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Værelse ikke tilgængeligt i valgte periode'; END IF; -- Opret booking INSERT INTO Bookinger ( gæst_id, værelse_id, check_ind_dato, check_ud_dato ) VALUES ( p_gæst_id, p_værelse_id, p_check_ind, p_check_ud ); COMMIT; END;
  3. Deadlock Prevention

    • Implementeret gennem:
      -- Sæt timeout for transaktioner SET innodb_lock_wait_timeout = 50; -- Monitor deadlocks SHOW ENGINE INNODB STATUS;
  4. Performance Optimering

    • Transaktions batch processing:
      START TRANSACTION; INSERT INTO Bookinger VALUES ROW(1, 101, '2024-03-20', '2024-03-25'), ROW(2, 102, '2024-03-21', '2024-03-24'), ROW(3, 103, '2024-03-22', '2024-03-26'); COMMIT;
  5. Recovery Procedures

    -- Ved system crash SELECT * FROM information_schema.innodb_trx; SELECT * FROM information_schema.innodb_locks; -- Gendan uafsluttede transaktioner XA RECOVER; XA ROLLBACK 'trx_id';

Test Documentation

Unit Tests

-- Test Suite: Booking System CREATE PROCEDURE test_booking_system() BEGIN -- Test Case 1: Valid Booking CALL sp_book_værelse(1, 101, '2024-04-01', '2024-04-05'); -- Test Case 2: Overlapping Booking (Should Fail) -- Expected: Error 45000 - 'Værelse ikke tilgængeligt i valgte periode' CALL sp_book_værelse(2, 101, '2024-04-03', '2024-04-07'); -- Test Case 3: Invalid Dates (Should Fail) -- Expected: Error 45000 - 'Invalid date range' CALL sp_book_værelse(3, 102, '2024-04-05', '2024-04-01'); END; -- Test Suite: Rabat System CREATE PROCEDURE test_rabat_system() BEGIN -- Test Case 1: FDM Medlem (12% rabat) INSERT INTO Bookinger (gæst_id, værelse_id, fdm_medlem) VALUES (1, 101, TRUE); -- Verify rabat SELECT CASE WHEN total_pris = basis_pris * 0.88 THEN 'TEST PASSED' ELSE 'TEST FAILED' END AS test_result FROM Bookinger WHERE booking_id = LAST_INSERT_ID(); END;

Integration Tests

#!/bin/bash # Integration Test Suite # Test 1: Database Connection mysql -u test_user -p'test_password' -h localhost cbzhotels -e "SELECT 1;" || exit 1 # Test 2: Backup System ./backup_test.sh || exit 1 # Test 3: Load Testing apache2-utils -n 1000 -c 100 http://localhost/booking-api || exit 1

Test Coverage Report

| Module | Lines | Coverage | Critical Paths Tested | |--------|-------|----------|---------------------| | Booking System | 456 | 92% | 15/15 | | User Management | 234 | 88% | 8/10 | | Payment Processing | 345 | 95% | 12/12 | | Reporting | 123 | 85% | 5/6 |

Test Environments

Development Environment

# dev-environment.conf SERVER=dev-cbzhotels.local DATABASE=cbzhotels_dev BACKUP_INTERVAL=daily DEBUG_MODE=true

Staging Environment

# staging-environment.conf SERVER=staging-cbzhotels.local DATABASE=cbzhotels_staging BACKUP_INTERVAL=6hours DEBUG_MODE=false

Production Environment

# prod-environment.conf SERVER=cbzhotels.local DATABASE=cbzhotels_prod BACKUP_INTERVAL=1hour DEBUG_MODE=false

Security Documentation

Backup and Recovery

# Daily Backup Procedure #!/bin/bash DATE=$(date +%Y%m%d) BACKUP_DIR="/var/backup/mysql" # Full backup mysqldump -u backup_user -p'${BACKUP_PASSWORD}' \ --all-databases \ --single-transaction \ --master-data=2 \ --triggers \ --routines \ > ${BACKUP_DIR}/full_${DATE}.sql # Compress backup gzip ${BACKUP_DIR}/full_${DATE}.sql # Verify backup gunzip -t ${BACKUP_DIR}/full_${DATE}.sql.gz || \ echo "Backup verification failed" | mail -s "Backup Error" admin@cbzhotels.dk

Recovery Procedure

-- Point-in-time Recovery Procedure CREATE PROCEDURE sp_recover_to_timestamp( IN p_timestamp DATETIME ) BEGIN -- 1. Stop all connections CALL sp_kill_all_connections(); -- 2. Restore full backup SOURCE /var/backup/mysql/full_backup.sql; -- 3. Apply binary logs until timestamp CALL sp_apply_binlog_to_timestamp(p_timestamp); -- 4. Verify data consistency CALL sp_verify_data_consistency(); END;

Password Policy

CREATE TRIGGER tr_password_policy BEFORE INSERT ON Users FOR EACH ROW BEGIN -- Check password length IF LENGTH(NEW.password) < 12 THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Password must be at least 12 characters'; END IF; -- Check password complexity IF NOT ( NEW.password REGEXP '[A-Z]' AND -- Upper case NEW.password REGEXP '[a-z]' AND -- Lower case NEW.password REGEXP '[0-9]' AND -- Numbers NEW.password REGEXP '[^A-Za-z0-9]' -- Special characters ) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Password must contain upper, lower, numbers and special chars'; END IF; END;

Data Encryption

-- At Rest Encryption ALTER TABLE Gæster ENCRYPTION = 'Y', ENCRYPTION_KEY_ID = 1; -- Sensitive Data Encryption CREATE PROCEDURE sp_encrypt_sensitive_data( IN p_data VARCHAR(255), OUT p_encrypted_data VARBINARY(255) ) BEGIN SET p_encrypted_data = AES_ENCRYPT( p_data, SHA2(@@encryption_key, 512) ); END;

GDPR Compliance

-- Data Retention Policy CREATE EVENT evt_data_retention ON SCHEDULE EVERY 1 DAY DO BEGIN -- Delete guest data older than 2 years DELETE FROM Gæster WHERE sidste_booking < DATE_SUB(NOW(), INTERVAL 2 YEAR) AND NOT EXISTS ( SELECT 1 FROM Bookinger WHERE Bookinger.gæst_id = Gæster.gæst_id AND check_ud_dato > DATE_SUB(NOW(), INTERVAL 2 YEAR) ); -- Anonymize historical data UPDATE Bookinger SET gæst_navn = 'ANONYMIZED', gæst_email = 'ANONYMIZED', gæst_telefon = 'ANONYMIZED' WHERE check_ud_dato < DATE_SUB(NOW(), INTERVAL 2 YEAR); END;

Server Dokumentation

Installation Guide

  1. Opdater systemet:
sudo apt update && sudo apt upgrade
  1. Installer MariaDB:
sudo apt install mariadb-server
  1. Kør sikkerhedskonfiguration:
sudo mysql_secure_installation
  1. Konfigurer backup:
# Opret backup directory sudo mkdir /var/backup/mysql sudo chown mysql:mysql /var/backup/mysql # Tilføj til crontab 0 1 * * * mysqldump -u backup_user -p'PASSWORD' --all-databases | gzip > /var/backup/mysql/full_backup_$(date +\%Y\%m\%d).sql.gz

Performance Tuning

# /etc/mysql/my.cnf [mysqld] innodb_buffer_pool_size = 1G innodb_log_file_size = 256M innodb_flush_log_at_trx_commit = 2 max_connections = 150

Login Oplysninger

| System | Brugernavn | Adgangskode | IP/Adresse | |--------|------------|-------------|------------| | MariaDB Admin | root | CBZ_admin2024! | 192.168.1.100 | | MariaDB Backup | backup_user | CBZ_backup2024! | 192.168.1.100 | | SSH Access | cbzadmin | CBZ_ssh2024! | 192.168.1.100 | | Monitoring | monitor | CBZ_monitor2024! | 192.168.1.100 |

Arbejdsfordeling

Plan over arbejdsfordeling

Logbog

| Dato | Aktivitet | Udført af | Bemærkninger | |------|-----------|-----------|--------------| | 04/03/2024 | Initial design | Mads | ER diagram udarbejdet | | 05/03/2024 | Tabel struktur | Mads | Normalisering gennemført | | 06/03/2024 | Views oprettet | Robin | Booking views implementeret | | 07/03/2024 | Testing | Robin | Performance test udført | | 08/03/2024 | Dokumentation | Robin | Første udkast færdig | | 11/03/2024 | Konference modul | Mads | Basis struktur implementeret | | 12/03/2024 | Personale tabeller | Mads | Roller defineret | | 13/03/2024 | Integration test | Robin | Systemtest gennemført | | 14/03/2024 | Optimering | Mads | Indeks tilføjet | | 15/03/2024 | Final review | Begge | System godkendt |

Ansvarsområder

Mads Iversen

Robin Pfeiffer

Diskussion

Tekniske Udfordringer

  1. Concurrent Booking Håndtering

    • Problem: Race conditions ved samtidige bookinger
    • Løsning: Implementeret transaktioner og row-level locking
    • Resultat: Sikker booking proces uden konflikter
  2. Performance Optimering

    • Problem: Langsom søgning i booking historik
    • Løsning: Implementeret composite indeks og partitionering
    • Resultat: 80% forbedring i søgetider
  3. Backup Strategy

    • Problem: Stort data volume
    • Løsning: Kombineret fuld backup og inkrementel backup
    • Resultat: Effektiv backup med minimal downtime

Fremtidige Forbedringer

  1. Implementering af real-time monitoring
  2. Automatiseret skalering af database ressourcer
  3. Integration med eksterne booking platforme

Konklusion

Systemet opfylder alle specificerede krav og er klar til produktion med:

Kilder og Referencer

  1. MySQL Documentation
  2. Database Design Best Practices
  3. Hotel Management Systems Research

Bilag

SQL Syntax

-- Eksempel på booking procedure CREATE PROCEDURE sp_opret_booking( IN p_gæst_id INT, IN p_hotel_id INT, IN p_værelse_id INT, IN p_check_ind DATE, IN p_check_ud DATE ) BEGIN -- Implementation END;

[^1]: Netværksdiagram udarbejdet i Visio 2024 [^2]: ER diagram lavet i MySQL Workbench [^3]: Klassediagram genereret med PlantUML [^4]: Database diagram eksporteret fra MySQL Workbench

Teknisk Dokumentation

Stored Procedures

-- Booking håndtering CREATE PROCEDURE sp_create_booking( IN p_guest_id INT, IN p_room_id INT, IN p_check_in DATE, IN p_check_out DATE, IN p_is_fdm BOOLEAN, IN p_is_online BOOLEAN ) BEGIN DECLARE v_total_price DECIMAL(10,2); DECLARE v_base_price DECIMAL(10,2); -- Get base price SELECT pris INTO v_base_price FROM Værelser WHERE værelse_id = p_room_id; -- Calculate price with discounts SET v_total_price = CASE WHEN p_is_fdm THEN v_base_price * 0.88 WHEN p_is_online THEN v_base_price * 0.90 ELSE v_base_price END; START TRANSACTION; -- Create booking INSERT INTO Bookinger ( gæst_id, værelse_id, check_ind_dato, check_ud_dato, total_pris, fdm_medlem, online_booking ) VALUES ( p_guest_id, p_room_id, p_check_in, p_check_out, v_total_price, p_is_fdm, p_is_online ); -- Update room status UPDATE Værelser SET status = 'Optaget' WHERE værelse_id = p_room_id; COMMIT; END; -- Personale administration CREATE PROCEDURE sp_assign_staff( IN p_staff_id INT, IN p_hotel_id INT, IN p_role_id INT ) BEGIN DECLARE v_current_staff INT; -- Check current staff count for role SELECT COUNT(*) INTO v_current_staff FROM Personale WHERE hotel_id = p_hotel_id AND rolle_id = p_role_id; -- Validate against maximum staff limits CASE p_role_id WHEN 1 THEN -- Stuepiger IF v_current_staff >= 3 THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Maksimum antal stuepiger nået'; END IF; WHEN 2 THEN -- Ledere IF v_current_staff >= 2 THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Maksimum antal ledere nået'; END IF; -- Add more role validations END CASE; -- Assign staff member INSERT INTO Personale ( personale_id, hotel_id, rolle_id ) VALUES ( p_staff_id, p_hotel_id, p_role_id ); END;

Views

-- Booking oversigt CREATE VIEW vw_booking_overview AS SELECT b.booking_id, h.hotel_navn, v.værelse_nummer, CONCAT(g.fornavn, ' ', g.efternavn) as gæst_navn, b.check_ind_dato, b.check_ud_dato, b.total_pris, CASE WHEN b.fdm_medlem THEN 'FDM' WHEN b.online_booking THEN 'Online' ELSE 'Standard' END as booking_type FROM Bookinger b JOIN Værelser v ON b.værelse_id = v.værelse_id JOIN Hoteller h ON v.hotel_id = h.hotel_id JOIN Gæster g ON b.gæst_id = g.gæst_id; -- Personale oversigt CREATE VIEW vw_staff_overview AS SELECT h.hotel_navn, r.rolle_navn, COUNT(*) as antal_ansatte, CASE r.rolle_id WHEN 1 THEN 3 - COUNT(*) WHEN 2 THEN 2 - COUNT(*) WHEN 3 THEN 8 - COUNT(*) WHEN 4 THEN 8 - COUNT(*) END as ledige_stillinger FROM Personale p JOIN Hoteller h ON p.hotel_id = h.hotel_id JOIN Personale_Roller r ON p.rolle_id = r.rolle_id GROUP BY h.hotel_id, r.rolle_id;

Triggers

-- Booking validering CREATE TRIGGER tr_validate_booking BEFORE INSERT ON Bookinger FOR EACH ROW BEGIN -- Check dates IF NEW.check_ud_dato <= NEW.check_ind_dato THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Check-ud dato skal være efter check-ind'; END IF; -- Check room availability IF EXISTS ( SELECT 1 FROM Bookinger WHERE værelse_id = NEW.værelse_id AND ( (check_ind_dato BETWEEN NEW.check_ind_dato AND NEW.check_ud_dato) OR (check_ud_dato BETWEEN NEW.check_ind_dato AND NEW.check_ud_dato) ) ) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Værelse ikke tilgængeligt i den valgte periode'; END IF; END; -- Audit log CREATE TRIGGER tr_audit_log AFTER INSERT ON Bookinger FOR EACH ROW BEGIN INSERT INTO Audit_Log ( tabel_navn, handling, record_id, ændret_af, ændret_dato ) VALUES ( 'Bookinger', 'INSERT', NEW.booking_id, CURRENT_USER(), NOW() ); END;

Sequence Diagrammer

Booking Process

sequenceDiagram participant G as Gæst participant B as Booking System participant D as Database participant M as Mail System G->>B: Anmod om booking B->>D: Check tilgængelighed D-->>B: Bekræft tilgængelighed B->>D: Opret booking D-->>B: Booking bekræftet B->>M: Send bekræftelse M->>G: Bekræftelsesmail

Check-in Process

sequenceDiagram participant G as Gæst participant R as Reception participant D as Database participant K as Kortsystem G->>R: Ankomst R->>D: Verificer booking D-->>R: Booking detaljer R->>K: Programmer nøglekort K-->>R: Kort programmeret R->>G: Udlever nøglekort

Deployment Diagram

graph TD subgraph Production LB[Load Balancer] WEB1[Web Server 1] WEB2[Web Server 2] DB1[(Primary DB)] DB2[(Replica DB)] end subgraph Backup BK[Backup Server] end LB --> WEB1 LB --> WEB2 WEB1 --> DB1 WEB2 --> DB1 DB1 --> DB2 DB1 --> BK

Data Flow Diagram

graph LR G[Gæst] --> |Booking request| BS[Booking System] BS --> |Validate| DB[(Database)] BS --> |Confirm| G DB --> |Update| RS[Reporting System] RS --> |Generate| R[Reports] DB --> |Backup| BK[Backup System]

Fejlhåndtering og Monitoring

Error Logging System

CREATE TABLE Error_Log ( log_id INT AUTO_INCREMENT PRIMARY KEY, error_code VARCHAR(10), error_message TEXT, stack_trace TEXT, user_id INT, ip_address VARCHAR(45), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, severity ENUM('LOW', 'MEDIUM', 'HIGH', 'CRITICAL'), status ENUM('NEW', 'IN_PROGRESS', 'RESOLVED', 'CLOSED') ); CREATE PROCEDURE sp_log_error( IN p_error_code VARCHAR(10), IN p_error_message TEXT, IN p_stack_trace TEXT, IN p_severity VARCHAR(10) ) BEGIN INSERT INTO Error_Log ( error_code, error_message, stack_trace, user_id, ip_address, severity ) VALUES ( p_error_code, p_error_message, p_stack_trace, CURRENT_USER(), CONNECTION_ID(), p_severity ); -- Send alert for critical errors IF p_severity = 'CRITICAL' THEN CALL sp_send_alert(LAST_INSERT_ID()); END IF; END;

Monitoring Setup

#!/bin/bash # System Health Check Script # Database Connections max_connections=$(mysql -e "SHOW VARIABLES LIKE 'max_connections';" | grep max_connections | awk '{print $2}') current_connections=$(mysql -e "SHOW STATUS LIKE 'Threads_connected';" | grep Threads_connected | awk '{print $2}') # Check connection threshold if [ $current_connections -gt $(($max_connections * 80 / 100)) ]; then echo "WARNING: High connection usage: $current_connections of $max_connections" ./send_alert.sh "High DB Connections" "CONNECTION_WARNING" fi # Check disk space disk_usage=$(df -h | grep '/database' | awk '{print $5}' | sed 's/%//') if [ $disk_usage -gt 85 ]; then echo "CRITICAL: High disk usage: $disk_usage%" ./send_alert.sh "Low Disk Space" "DISK_CRITICAL" fi # Check replication status slave_status=$(mysql -e "SHOW SLAVE STATUS\G" | grep "Slave_IO_Running: Yes" | wc -l) if [ $slave_status -eq 0 ]; then echo "CRITICAL: Replication not running" ./send_alert.sh "Replication Failed" "REPLICATION_ERROR" fi

Performance Monitoring

CREATE VIEW vw_performance_metrics AS SELECT VARIABLE_NAME, VARIABLE_VALUE FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME IN ( 'Queries', 'Slow_queries', 'Threads_connected', 'Created_tmp_disk_tables', 'Handler_read_first', 'Handler_read_rnd', 'Handler_read_rnd_next' ); CREATE EVENT evt_performance_snapshot ON SCHEDULE EVERY 5 MINUTE DO BEGIN INSERT INTO Performance_History SELECT * FROM vw_performance_metrics; -- Check for performance issues CALL sp_analyze_performance(); END;

Vedligeholdelsesplaner

Database Maintenance

CREATE PROCEDURE sp_daily_maintenance() BEGIN -- Optimize frequently used tables OPTIMIZE TABLE Bookinger; OPTIMIZE TABLE Gæster; OPTIMIZE TABLE Værelser; -- Update statistics ANALYZE TABLE Bookinger; ANALYZE TABLE Gæster; ANALYZE TABLE Værelser; -- Clean old audit logs DELETE FROM Audit_Log WHERE created_at < DATE_SUB(NOW(), INTERVAL 6 MONTH); -- Archive old bookings INSERT INTO Booking_Archive SELECT * FROM Bookinger WHERE check_ud_dato < DATE_SUB(NOW(), INTERVAL 2 YEAR); -- Delete archived bookings DELETE FROM Bookinger WHERE check_ud_dato < DATE_SUB(NOW(), INTERVAL 2 YEAR); END; CREATE EVENT evt_daily_maintenance ON SCHEDULE EVERY 1 DAY STARTS (CURRENT_DATE + INTERVAL 1 DAY + INTERVAL 2 HOUR) DO BEGIN CALL sp_daily_maintenance(); END;

Backup Schedule

-- Full backup hver nat CREATE EVENT evt_nightly_backup ON SCHEDULE EVERY 1 DAY STARTS (CURRENT_DATE + INTERVAL 1 DAY + INTERVAL 1 HOUR) DO BEGIN CALL sp_full_backup(); END; -- Inkrementel backup hver time CREATE EVENT evt_hourly_incremental ON SCHEDULE EVERY 1 HOUR DO BEGIN CALL sp_incremental_backup(); END;

System Updates

#!/bin/bash # Weekly System Update Script # Set maintenance window MAINTENANCE_START=$(date +%H:%M:%S) echo "Maintenance window started at $MAINTENANCE_START" # Notify users ./notify_users.sh "System maintenance starting" # Stop application services systemctl stop cbzhotels-webapp systemctl stop cbzhotels-api # Backup before updates ./backup.sh pre-update # Update system packages apt update && apt upgrade -y # Update database mysql_upgrade -u root -p # Start services systemctl start cbzhotels-api systemctl start cbzhotels-webapp # Verify system health ./health_check.sh # Notify completion ./notify_users.sh "System maintenance completed"

Performance Tuning

# /etc/mysql/conf.d/performance.cnf [mysqld] # InnoDB settings innodb_buffer_pool_size = 4G innodb_log_file_size = 512M innodb_flush_log_at_trx_commit = 2 innodb_flush_method = O_DIRECT # Query cache settings query_cache_type = 1 query_cache_size = 128M query_cache_limit = 2M # Connection settings max_connections = 500 thread_cache_size = 128

Incident Response Plan

## Incident Response Procedure 1. Initial Assessment - Identify severity level - Log incident details - Notify relevant team members 2. Immediate Actions - High-severity: Initiate war room - Medium-severity: Assign to on-call team - Low-severity: Schedule for next business day 3. Resolution Steps - Investigate root cause - Implement fix - Verify solution - Document findings 4. Post-Incident - Conduct post-mortem - Update procedures - Implement preventive measures

Disaster Recovery

CREATE PROCEDURE sp_disaster_recovery( IN p_recovery_point DATETIME ) BEGIN -- 1. Stop all connections CALL sp_kill_all_connections(); -- 2. Switch to backup server CALL sp_activate_backup_server(); -- 3. Restore from backup CALL sp_restore_from_backup(p_recovery_point); -- 4. Verify data integrity CALL sp_verify_data_integrity(); -- 5. Switch DNS CALL sp_update_dns(); -- 6. Notify stakeholders CALL sp_send_recovery_notification(); END;