J'ai un système Joomla-3.9 et Apache-2.4.34 sur Fedora29 avec Mariadb-10.2.19 et les tables contenant le contenu de la recherche sont très grandes. Plusieurs sont supérieurs à 1,2 Go et l'une est supérieure à 5,5 Go. Supprimer des articles prend vraiment longtemps.
Le système sur lequel il s'exécute est un processeur Intel (R) Xeon (R) CPU E5-2623 V3 @ 300GHz avec 64 Go de RAM et un SSD RAID5. Il n'y a vraiment aucune autre activité .
Quelles options sont là pour améliorer les performances? J'ai fait un réglage de base de Mariahb, mais il n'ya vraiment pas grand chose que je puisse faire à la base de données elle-même.
Est-ce ce que Galera est pour? Mettre la base de données dans une aide de Ramdisk?
Qu'est-ce qui est impliqué dans le déplacer vers AWS?
Changerait-il à un autre système de fichiers autre que EXT4 faire une différence appréciable?
Je pensais à mettre uniquement les tables de recherche sur un SSD séparé sans raid5 puisqu'ils peuvent être reconstruits si facilement, mais je ne pouvais pas comprendre comment les découpler du reste de la base de données.
Voici ma configuration My.cnf pour ce système. Y a-t-il d'autres modifications de réglage que vous apporteriez pour améliorer les performances?
[client]
port = 3306
socket = /var/lib/mysql/mysql.sock
[mysqld]
port = 3306
socket = /var/lib/mysql/mysql.sock
skip-external-locking
key_buffer_size = 256M
max_allowed_packet = 16M
table_open_cache = 256
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 4M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size= 16M
thread_concurrency = 8
relay_log_space_limit = 500M
relay_log_purge = 1
log-slave-updates = 1
max_heap_table_size = 256M
tmp_table_size = 256M
relay-log=bwimail01-relay-bin
log_bin = /var/log/mariadb/mysql-bin.log
expire_logs_days = 5
max_binlog_size = 100M
plugin_load=server_audit=server_audit.so
server_audit_events=connect,query
server_audit_file_path = /var/log/mariadb/server_audit.log
server_audit_file_rotate_size = 1G
server_audit_file_rotations = 1
slow-query-log = 1
slow-query-log-file = /var/log/mariadb/mariadb-slow.log
long_query_time = 1
log_error = /var/log/mariadb/mariadb-error.log
binlog_format=mixed
server-id = 5
report-Host=bwimail01.example.com
innodb_data_home_dir = /var/lib/mysql
innodb_defragment=1
innodb_file_per_table
innodb_flush_log_at_trx_commit = 2
innodb_data_file_path = ibdata1:10M:autoextend:max:500M
innodb_buffer_pool_size=850M
innodb_log_file_size = 64M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method=O_DIRECT
innodb_lock_wait_timeout = 50
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
no-auto-rehash
[myisamchk]
key_buffer_size = 128M
sort_buffer_size = 128M
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout
eDIT: Voici "Show Create Create Finder_Links"
Finder_links | CREATE TABLE `Finder_links` (
`link_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`url` varchar(255) NOT NULL,
`route` varchar(255) NOT NULL,
`title` varchar(400) DEFAULT NULL,
`description` text DEFAULT NULL,
`indexdate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`md5sum` varchar(32) DEFAULT NULL,
`published` tinyint(1) NOT NULL DEFAULT 1,
`state` int(5) DEFAULT 1,
`access` int(5) DEFAULT 0,
`language` varchar(8) NOT NULL,
`publish_start_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`publish_end_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`start_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`end_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`list_price` double unsigned NOT NULL DEFAULT 0,
`sale_price` double unsigned NOT NULL DEFAULT 0,
`type_id` int(11) NOT NULL,
`object` mediumblob NOT NULL,
PRIMARY KEY (`link_id`),
KEY `idx_type` (`type_id`),
KEY `idx_title` (`title`(100)),
KEY `idx_md5` (`md5sum`),
KEY `idx_url` (`url`(75)),
KEY `idx_published_list`
(`published`,`state`,`access`,`publish_start_date`,`publish_end_date`,`list_price`),
KEY `idx_published_sale`
(`published`,`state`,`access`,`publish_start_date`,`publish_end_date`,`sal e_price`)
) ENGINE=InnoDB AUTO_INCREMENT=62705 DEFAULT CHARSET=utf8mb4
Une partie du problème est que, parce que cela fait partie de Joomla, je n'ai vraiment aucun contrôle sur la manière dont les tables sont organisées, quels changements je peux apporter pour améliorer le schéma, ou comment j'organise les écritures.
Il semble qu'il y ait un tas de requêtes lentes similaires à celles-ci:
INSERT IGNORE INTO `xu5gc_Finder_terms`
(`term`, `stem`, `common`, `phrase`, `weight`, `soundex`, `language`)
SELECT ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight,
SOUNDEX(ta.term), ta.language
FROM `xu5gc_Finder_tokens_aggregate` AS ta
WHERE ta.term_id = 0
GROUP BY ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight,
SOUNDEX(ta.term), ta.language;
INSERT INTO `xu5gc_Finder_tokens_aggregate`
(`term_id`, `map_suffix`,
`term`, `stem`, `common`, `phrase`, `term_weight`, `context`,
`context_weight`, `total_weight`, `language`)
SELECT COALESCE(t.term_id, 0), '', t1.term, t1.stem, t1.common,
t1.phrase, t1.weight, t1.context,
ROUND( t1.weight * COUNT( t2.term ) * 0.700000, 8 ) AS context_weight,
0, t1.language
FROM (
SELECT DISTINCT t1.term, t1.stem, t1.common, t1.phrase, t1.weight,
t1.context, t1.language
FROM `xu5gc_Finder_tokens` AS t1
WHERE t1.context = 2
) AS t1
JOIN `xu5gc_Finder_tokens` AS t2 ON t2.term = t1.term
LEFT JOIN `xu5gc_Finder_terms` AS t ON t.term = t1.term
WHERE t2.context = 2
GROUP BY t1.term, t.term_id, t1.term, t1.stem, t1.common,
t1.phrase, t1.weight, t1.context, t1.language
ORDER BY t1.term DESC;
et
UPDATE `xu5gc_Finder_terms` AS t
INNER JOIN `xu5gc_Finder_tokens_aggregate` AS ta
ON ta.term_id = t.term_id
SET t.`links` = t.links + 1;
SET timestamp=1546570831;
SELECT DISTINCT t.term_id AS id, t.term AS term
FROM xu5gc_Finder_terms AS t
WHERE t.soundex = SOUNDEX('2018 2594-1')
AND t.phrase = 1;
EDIT: Ajout d'informations supplémentaires demandées. Il fonctionne depuis environ 24 heures maintenant, mais c'est un système de développement, donc il n'y a pas vraiment beaucoup d'activité en ce moment.
Afficher les variables globales
[.____] https://pastebin.com/w0bpktu5
Afficher le statut global
[.____] https://pastebin.com/gb0aqut6
Tables Finder (Afficher l'index de et explique)
[.____] xu5gc_finder_TERMS est la table de 5,4 Go
[.____] https://pastebin.com/rjxts9sp
MySQLTUNER-PERL-MASTER
[.____] https://pastebin.com/aw6f0umj
Journal d'erreur MariDB (/var/log/mariadb/mariadb-error.log)
https://pastebin.com/ee8q0k1d
Je pensais qu'il serait peut-être utile d'avoir quelques images. S'il vous plaît laissez-moi savoir si d'autres statistiques seraient utiles.
EDIT: Ajout de la sortie ulimit (en tant que root):
# ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 128545
max locked memory (kbytes, -l) 16384
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 128545
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
Analyse des variables et du statut global:
Observations :
Les problèmes les plus importants :
innodb_io_capacity
peut probablement être augmenté à 1000, peut-être plus.
Dans ce serveur, Galera est désactivé. L'avez-vous pour la production? Si vous utilisez une réplication normale, envisagez sync_binlog = ON
.
6 analyses de table/seconde. La moitié des requêtes impliquent une numérisation de table. Voyons plus de vos questions. (Seulement 79 passes de trimes-fusion par heure.)
Utilisez-vous NDB Cluster? (Je vois Handler_Discover.)
(Merci: de bons paramètres pour Slowlog.)
innodb_use_atomic_writes
- est le matériel du contrôleur RAID ? Quelle marque? Est-ce que cela prend en charge Atomic 16kb écrit?
engine_condition_pushdown = off
-- Pourquoi?
détails et autres observations :
( innodb_buffer_pool_size / _ram ) = 15360M / 65536M = 23.4%
-% de RAM utilisé pour Innodb Buffer_pool (mais vous n'avez pas suffisamment de données pour que cela soit de plus en plus utile)
( ( Binlog_commits - Binlog_group_commits ) / Binlog_group_commits ) = ( 74938 - 74938 ) / 74938 = 0
- PCT des commits qui auraient pu être effectués en parallèle - augmentation binlog_commit_wait_usec et/ou binlog_commit_wait_count sur le maître.
( innodb_page_cleaners / innodb_buffer_pool_instances ) = 4 / 15 = 0.267
- Page_Cleaners - Recommander Réglage Innodb_Page_Cleaners à Innodb_Buffer_pool_Instances
( innodb_lru_scan_depth ) = 1,024
- "InnoDB: Page_Cleaner: 1000ms à la boucle de la boucle souhaitée ..." peut être corrigé en abaissant LRU_SCAN_DEPTH
( Innodb_buffer_pool_pages_free * 16384 / innodb_buffer_pool_size ) = 705,616 * 16384 / 15360M = 71.8%
- Buffer Pool Free - Buffer_Pool_Size est plus grand que le jeu de travail; pourrait le diminuer
( Innodb_buffer_pool_pages_free / Innodb_buffer_pool_pages_total ) = 705,616 / 983040 = 71.8%
- PCT de buffer_pool actuellement pas utilisé - innodb_buffer_pool_size est plus gros que nécessaire?
( Innodb_buffer_pool_bytes_data / innodb_buffer_pool_size ) = 4,475,404,288 / 15360M = 27.8%
- Pourcentage de la piscine tampon prise par des données - un petit pour cent peut indique que le buffer_pool est inutilement grand.
( Uptime / 60 * innodb_log_file_size / Innodb_os_log_written ) = 74,340 / 60 * 1024M / 465657856 = 2,856
- minutes entre les rotations de journaux Innodb commençant par 5.6.8, cela peut être modifié de manière dynamique; Assurez-vous également de changer mon.cnf. - (La recommandation de 60 minutes entre les rotations est quelque peu arbitraire.) Ajustez Innodb_Log_File_Size. (Ne peut pas changer d'AWS.)
( innodb_io_capacity ) = 200
- E/S ops par seconde capable sur disque. 100 pour les lecteurs lents; 200 pour tourner les lecteurs; 1000-2000 pour les SSD; multiplier par le facteur RAID.
( sync_binlog ) = 0
- Utilisez 1 pour une sécurité supplémentaire, à certains frais d'E/S = 1 peut conduire à beaucoup de "fin de requête"; = 0 peut conduire à "Binlog en position impossible" et à perdre des transactions dans un accident, mais est plus rapide.
( innodb_print_all_deadlocks ) = innodb_print_all_deadlocks = OFF
- Si vous souhaitez connecter toutes les impasses. - Si vous êtes en proie à des blocages, tournez-le. Attention: Si vous avez beaucoup d'impasse, cela peut écrire beaucoup sur le disque.
( join_buffer_size / _ram ) = 1M / 65536M = 0.00%
- 0-N par fil. Peut accélérer les jointures (mieux pour corriger les requêtes/index) (tous les moteurs) utilisés pour la numérisation d'index, la numérisation de l'index de plage, la numérisation de la table complète, chaque jointure complète, etc. - si grande, diminuez Join_Buffer_Size pour éviter la pression de la mémoire. Suggérer moins de 1% de RAM. Si petit, augmentez à 0,01% de RAM pour améliorer certaines requêtes.
( net_buffer_length / max_allowed_packet ) = 16,384 / 16M = 0.10%
( local_infile ) = local_infile = ON
- local_infile = sur est un problème de sécurité potentiel
( bulk_insert_buffer_size / _ram ) = 8M / 65536M = 0.01%
- Tampon pour les inserts de plusieurs rangées et les données de charge - trop petit pourrait entraver ces opérations.
( tmp_table_size ) = 256M
- limiter la taille de [~ # ~] mémoire [~ # ~] Tables Temps utilisées pour supporter une sélection - Diminuer TMP_TABLE_SIZE pour éviter à court de bélier. Peut-être pas plus de 64 m.
( (Com_insert + Com_update + Com_delete + Com_replace) / Com_commit ) = (20260 + 69883 + 2901 + 0) / 62678 = 1.48
- Déclarations par commis (en supposant que tout InnoDB) - Basse: pourrait aider à recruter des requêtes dans les transactions.
( Select_scan ) = 448,754 / 74340 = 6 /sec
- Analyse de la table complète - Ajouter des index/Optimiser les requêtes (sauf si elles sont de minuscules tables)
( Select_scan / Com_select ) = 448,754 / 871456 = 51.5%
-% de sélection de la table de la table complète. (Peut être dupe de routines stockées.) - Ajouter des index/optimiser les requêtes
( relay_log_space_limit ) = 500M
- La taille totale maximale pour les journaux relais sur un esclave. (0 = illimité) - discutons de la justification d'une limite.
( binlog_format ) = binlog_format = MIXED
- Déclaration/ligne/mixte. La ligne est préférée; Cela peut devenir la valeur par défaut.
( wsrep_log_conflicts ) = wsrep_log_conflicts = OFF
- Si vous obtenez des conflits d'impasse pendant commettre, ce drapeau peut être utile.
( back_log / max_connections ) = 80 / 151 = 53.0%
Anormalement petit:
Handler_read_next / Handler_read_key = 0.647
Innodb_secondary_index_triggered_cluster_reads = 7.8MB
Rows_tmp_read = 2.3MB
eq_range_index_dive_limit = 0
innodb_log_block_size = 0
innodb_max_bitmap_file_size = 0
innodb_max_changed_pages = 0
innodb_mirrored_log_groups = 0
innodb_sched_priority_cleaner = 0
innodb_show_locks_held = 0
lock_wait_timeout = 86400
slave_net_timeout = 60
Anormalement grand:
Com_show_binlogs = 25 /HR
Com_show_engine_status = 26 /HR
Com_show_plugins = 25 /HR
Com_show_slave_hosts = 0.15 /HR
Com_show_slave_status = 0.04 /sec
Handler_discover = 27 /HR
Innodb_buffer_pool_pages_flushed / max(Questions, Queries) = 1
Innodb_buffer_pool_pages_free = 705,616
Innodb_system_rows_deleted = 0.81 /sec
Innodb_system_rows_inserted = 0.81 /sec
Innodb_system_rows_read = 60,203
Opened_plugin_libraries = 0.097 /HR
Performance_schema_file_classes_lost = 1
Slave_received_heartbeats = 656
Slaves_running = 1
group_concat_max_len = 1MB
innodb_adaptive_hash_index_partitions = 8
max_relay_log_size = 100MB
Cordes anormales:
Slave_running = ON
binlog_annotate_row_events = ON
innodb_buffer_pool_dump_at_shutdown = ON
innodb_buffer_pool_load_at_startup = ON
innodb_corrupt_table_action = deprecated
innodb_data_home_dir = /var/lib/mysql
innodb_defragment = ON
innodb_fast_shutdown = 1
innodb_file_format = Barracuda
innodb_file_format_max = Barracuda
innodb_large_prefix = ON
innodb_locking_fake_changes = OFF
innodb_undo_directory = ./
innodb_use_atomic_writes = ON
innodb_use_global_flush_log_at_trx_commit = OFF
innodb_use_trim = ON
log_slow_admin_statements = ON
log_slow_slave_statements = ON
myisam_stats_method = NULLS_UNEQUAL
opt_s__engine_condition_pushdown = off
replicate_annotate_row_events = ON
Heads Up : Cela vous limite à une minuscule 0.5 Go de données et d'index innodubes:
"innodb_data_file_path": "ibdata1: 10m: autoextend: max: 500m"
Conseils sur les requêtes lentes. Ceci est une liste de suggestions wimpy, CREATE TABLE
Et les tailles de table peuvent vous aider.
Est-ce que le INSERT...SELECT
Est fait à plusieurs reprises? Pourrait-il être fait progressivement? Comme dans, copier les données d'aujourd'hui aujourd'hui, mais pas encore demain?
xu5gc_Finder_tokens_aggregate
- Considérez le pré-calcul SOUNDEX(term)
dans une autre colonne, plutôt que de le traiter dans le SELECT
.
Le SELECT ... FROM xu5gc_Finder_tokens_aggregate
Doit lire la table entière, construire une temp, alors GROUP BY
. Repenser si vous avez besoin de beaucoup de sortie. Attendre! Pourquoi y a-t-il un GROUP BY
? Il n'y a pas d'agrégats ??
WHERE t.soundex = SOUNDEX('2018 2594-1') AND t.phrase = 1
Besoins INDEX(phrase, soundex)
(dans l'un ou l'autre ordre).
JOIN t2 ON t2.term = t1.term ... WHERE t2.context = 2
mai Travailler mieux que JOIN t2 ON t2.term = t1.term AND t2.context = t1.context
Puisque le contexte est identique. Ensuite, INDEX(term, context)
(dans l'un ou l'autre ordre) serait probablement bénéfique.
Sont term
et term_id
1: 1? Le regroupement et l'adhésion ne semblent pas être cohérents sur lesquels utiliser. IT Peut-être Vérifiez la peine de vous débarrasser de term_id
Et de promouvoir term
pour être le PRIMARY KEY
?
Mon mantra: "Vous ne pouvez lancer que du matériel à un problème de performance une fois; il vaut mieux rechercher une solution logicielle."
La suppression de nombreux lignes est coûteuse car elle enregistre les anciennes lignes en cas de panne de courant (ou d'un autre accident ou besoin de ROLLBACK
).
S'il s'agit d'un petit nombre de lignes, vous n'avez peut-être pas d'index approprié? Veuillez donner SHOW CREATE TABLE
et la déclaration DELETE
.
S'il s'agit d'un grand nombre de lignes, il est préférable de le faire dans des morceaux.
S'il s'agit d'un processus répétitif, tel que l'élimination des enregistrements de plus d'un mois, alors PARTITION BY RANGE
peut être très bénéfique.
Les deux derniers cas sont couverts ici .
En règle générale, vous ne pouvez pas régler le problème d'un problème de performance "; Cependant, je vois une chose ou deux qui n'est pas correctement accordée:
64GB of RAM with a 5.5GB table and innodb_buffer_pool_size=850M
Ce réglage peut être élevé à 70% de disponible RAM. Mais même 10g devrait être bénéfique.
Re, vos références:
Do pas Utilisez un RAMDISK.
AWS pourrait ou pourrait ne pas aider. Ils auraient mis le tampon_pool à une taille raisonnable, mais il pourrait y avoir d'autres problèmes.
L'utilisation principale de Galera est destinée à ha (haute disponibilité) - survivre au crash d'un serveur avec pratiquement aucun hoquet.
Un système de fichiers différent ne serait pas "aiderait sensiblement".
RAID5 avec SSDS est sans doute la meilleure façon d'aller; Ne vous éloigez pas. J'espère que cela inclut un contrôleur de raid matériel avec le cache d'écriture sauvegardé par batterie? C'est Mieux Pour laisser le raid gérer les accès que de jouer manuellement avec le placement des tables (fichiers).
Quères
Indices souhaitables:
xu5gc_Finder_tokens_aggregate: INDEX(term_id) -- for insert..select #1 & Update
xu5gc_Finder_tokens: INDEX(context, term) -- in that order.
xu5gc_Finder_terms: INDEX(term)
xu5gc_Finder_terms: INDEX(term_id)
xu5gc_Finder_terms: INDEX(phase, soundex, -- first, in either order
term, term_id) -- in either order (for 'covering')
(Il pourrait être utile de voir SHOW CREATE TABLE
.)
Taux par seconde = Suggestions RPS à prendre en compte pour votre section my.cnff [mysqld]
innodb_io_capacity=1900 # from 200 to enable SSD additional IOPS
read_rnd_buffer_size=512K # ~4M to reduce handler_read_rnd_next RPS of 7,601
innodb_lru_scan_depth=100 # from 1024 to reduce CPU busy cycles 90% for this function
innodb_log_buffer_size=16M # from 8M to support ~ 30 minutes in buffer before WD
table_definition_cache=500 # from 500 to reduce opened_table_definitions count
Dans l'attente de vos résultats de Ulimit -a. Votre système d'exploitation est probablement limitant le nombre de poignées de fichier ouverts à la disposition de MySQL pour la gestion de la table.
Pour des suggestions supplémentaires, veuillez consulter mon profil, le profil de réseau contient des informations de contact.
13 janvier 2019 02:20 Alex, vous êtes correct, les fichiers ouverts de 1024 sont trop bas pour votre niveau d'activité.
Suggestion pour votre ulimit -a à prendre en compte s'il vous plaît à partir de l'invite de commande Linux,
ulimit -n 16384 # à partir de 1024 pour activer davantage de poignées de fichier OS d'être active.
Ce qui précède est dynamique avec Linux OS. Les services d'arrêt/de départ auraient accès aux poignées.
Pour rendre cela persistant à travers l'arrêt/le redémarrage du système d'exploitation, consultez cette URL pour des instructions de système d'exploitation similaires.
Ces instructions définissent 500 000 pour le fichier-max, veuillez définir votre capacité à 16384 pour l'instant.
ulimit Veuillez définir 16384, ce qui permettra à MySQL d'utiliser 1206 demandées
et avoir des pièces de rechange pour d'autres applications
https://glassonionblog.wordpress.com/2013/01/27/Increase-ulimit-and-file-Descriptors-limit/
Dans l'attente de votre contact par Skype. Mon identifiant Skype est [email protected] Merci pour votre dernier commentaire.
Premièrement, RAID5 est très faible pour écrit et supprimer en fait beaucoup d'entre eux.
Lorsque vous faites une grosse suppression, tout est écrit pour vous connecter d'abord, la récupération peut donc se produire s'il y a un crash. Si vos journaux sont sur votre tableau RAID 5, déplacez-les ailleurs - de préférence un tableau RAID 1 (en miroir), sinon vous avez une affirmation massive.
Il peut être utile de supprimer certains index et de les reconstruire après, car il lit les données à supprimer, écrit tout ce que vous êtes en train de se connecter, puis va à travers le journal de la ligne Supprime la ligne de la ligne, y compris des index, donc si vous avez plus index il faudra plus longtemps.