Mysql
 sql >> база данни >  >> RDS >> Mysql

Сравнение на производителността на MySQL:MySQL 5.7 срещу MySQL 8.0

MySQL 8.0 донесе огромни промени и модификации, наложени от екипа на Oracle MySQL. Физическите файлове са променени. Например *.frm, *.TRG, *.TRN и *.par вече не съществуват. Добавени са тонове нови функции като CTE (Общи таблични изрази), функции на прозореца, невидими индекси, regexp (или регулярен израз) - последният е променен и вече осигурява пълна поддръжка на Unicode и е многобайтов безопасен. Речникът на данните също е променен. Сега е включен в речник на транзакционни данни, който съхранява информация за обекти на база данни. За разлика от предишните версии, данните от речника се съхраняват във файлове с метаданни и не-транзакционни таблици. Сигурността е подобрена с новото добавяне на caching_sha2_password, което вече е удостоверяването по подразбиране, заменящо mysql_native_password и предлага повече гъвкавост, но засилена сигурност, която трябва да използва или защитена връзка, или некриптирана връзка, която поддържа обмен на пароли с помощта на двойка ключове RSA.

С всички тези страхотни функции, подобрения, подобрения, които MySQL 8.0 предлага, нашият екип се интересуваше да определи колко добре се представя текущата версия на MySQL 8.0, особено като се има предвид, че нашата поддръжка за версии на MySQL 8.0.x в ClusterControl е на път (така че следете по този). Тази публикация в блога няма да обсъжда функциите на MySQL 8.0, но възнамерява да сравни производителността му с MySQL 5.7 и да видим как се е подобрила тогава.

Настройка и среда на сървъра

За този сравнителен тест възнамерявам да използвам минимална настройка за производство, използвайки следната среда AWS EC2:

Тип на екземпляра:t2.xlarge instance
Съхранение:gp2 (SSD съхранение с минимум 100 и максимум 16000 IOPS)
vCPUS:4
Памет:16GiB
MySQL 5.7 версия:MySQL Community Server (GPL) 5.7.24
Версия на MySQL 8.0:MySQL Community Server - GPL 8.0.14

Има няколко забележителни променливи, които съм задал и за този показател, които са:

  • innodb_max_dirty_pages_pct =90 ## Това е стойността по подразбиране в MySQL 8.0. Вижте тук за подробности.
  • innodb_max_dirty_pages_pct_lwm=10 ## Това е стойността по подразбиране в MySQL 8.0
  • innodb_flush_neighbors=0
  • innodb_buffer_pool_instances=8
  • innodb_buffer_pool_size=8GiB

Останалите променливи, които се задават тук и за двете версии (MySQL 5.7 и MySQL 8.0), вече са настроени от ClusterControl за неговия шаблон my.cnf.

Също така потребителят, който използвах тук, не отговаря на новото удостоверяване на MySQL 8.0, което използва caching_sha2_password. Вместо това и двете версии на сървъра използват mysql_native_password плюс променливата innodb_dedicated_server е ИЗКЛЮЧЕНА (по подразбиране), което е нова функция на MySQL 8.0.

За да улесня живота, настроих възела на версията на MySQL 5.7 на общността с ClusterControl от отделен хост, след което премахнах възела в клъстер и изключих хоста на ClusterControl, за да направя възела на MySQL 5.7 неактивен (без мониторинг на трафика). Технически и двата възела MySQL 5.7 и MySQL 8.0 са неактивни и няма активни връзки през възлите, така че по същество това е чист тест за сравнителен анализ.

Използвани команди и скриптове

За тази задача sysbench се използва за тестване и симулация на натоварване за двете среди. Ето следните команди или скрипт, използвани в този тест:

sb-prepare.sh

#!/bin/bash

host=$1
#host192.168.10.110
port=3306
user='sysbench'
password='[email protected]'
table_size=500000
rate=20
ps_mode='disable'
sysbench /usr/share/sysbench/oltp_read_write.lua --db-driver=mysql --threads=1 --max-requests=0 --time=3600 --mysql-host=$host --mysql-user=$user --mysql-password=$password --mysql-port=$port --tables=10 --report-interval=1 --skip-trx=on --table-size=$table_size --rate=$rate --db-ps-mode=$ps_mode prepare

sb-run.sh

#!/usr/bin/env bash

host=$1
port=3306
user="sysbench"
password="[email protected]"
table_size=100000
tables=10
rate=20
ps_mode='disable'
threads=1
events=0
time=5
trx=100
path=$PWD

counter=1

echo "thread,cpu" > ${host}-cpu.csv

for i in 16 32 64 128 256 512 1024 2048; 
do 

    threads=$i

    mysql -h $host -e "SHOW GLOBAL STATUS" >> $host-global-status.log
    tmpfile=$path/${host}-tmp${threads}
    touch $tmpfile
    /bin/bash cpu-checker.sh $tmpfile $host $threads &

    /usr/share/sysbench/oltp_read_write.lua --db-driver=mysql --events=$events --threads=$threads --time=$time --mysql-host=$host --mysql-user=$user --mysql-password=$password --mysql-port=$port --report-interval=1 --skip-trx=on --tables=$tables --table-size=$table_size --rate=$rate --delete_inserts=$trx --order_ranges=$trx --range_selects=on --range-size=$trx --simple_ranges=$trx --db-ps-mode=$ps_mode --mysql-ignore-errors=all run | tee -a $host-sysbench.log

    echo "${i},"`cat ${tmpfile} | sort -nr | head -1` >> ${host}-cpu.csv
    unlink ${tmpfile}

    mysql -h $host -e "SHOW GLOBAL STATUS" >> $host-global-status.log
done

python $path/innodb-ops-parser.py $host

mysql -h $host -e "SHOW GLOBAL VARIABLES" >> $host-global-vars.log

Така скриптът просто подготвя sbtest схемата и попълва таблици и записи. След това извършва тестове за четене/запис, използвайки скрипт /usr/share/sysbench/oltp_read_write.lua. Скриптът изхвърля глобалното състояние и MySQL променливите, събира използването на процесора и анализира операциите с редове на InnoDB, обработвани от скрипт innodb-ops-parser.py. След това скриптовете генерират *.csv файлове въз основа на изхвърлените регистрационни файлове, които бяха събрани по време на сравнителния анализ, след което използвах електронна таблица на Excel тук, за да генерирам графиката от *.csv файлове. Моля, проверете кода тук в това хранилище на github.

Сега, нека продължим с резултатите от графиката!

Операции с ред в InnoDB

По принцип тук извадих само операциите с редове InnoDB, които извършват селектиране (четене), изтриване, вмъкване и актуализиране. Когато броят на нишките се увеличи, MySQL 8.0 значително превъзхожда MySQL 5.7! И двете версии нямат никакви специфични промени в конфигурацията, а само забележителните променливи, които съм задал. Така че и двете версии почти използват стойности по подразбиране.

Интересно е, че по отношение на твърденията на екипа на MySQL Server относно производителността на четене и запис в новата версия, графиките сочат значително подобрение на производителността, особено при сървър с високо натоварване. Представете си разликата между MySQL 5.7 спрямо MySQL 8.0 за всичките му операции с редове в InnoDB, има голяма разлика, особено когато броят на нишките се увеличава. MySQL 8.0 разкрива, че може да работи ефективно, независимо от работното си натоварване.

Транзакциите са обработени

Както е показано на графиката по-горе, производителността на MySQL 8.0 отново показва огромна разлика във времето, необходимо за обработка на транзакции. Колкото по-ниско, толкова по-добре се представя, което означава, че е по-бързо за обработка на транзакции. Обработените транзакции (втората графика) също разкрива, че и двата броя транзакции не се различават една от друга. Това означава, че и двете версии изпълняват почти същия брой транзакции, но се различават по това колко бързо може да завърши. Въпреки че мога да кажа, че MySQL 5.7 все още може да се справи с много при по-ниско натоварване, но реалистичното натоварване, особено в производството, може да се очаква да бъде по-високо – особено в най-натоварения период.

Графиката по-горе все още показва транзакциите, които е успял да обработи, но разделя четенето от записа. Въпреки това, всъщност има отклонения в графиките, които не включих, тъй като те са малки късчета от резултата, които биха изкривили графиката.

MySQL 8.0 разкрива страхотни подобрения, особено за извършване на четене. Той показва своята ефективност при писане, особено за сървъри с голямо натоварване. Някои страхотни добавени поддръжка, които оказват влияние върху производителността на MySQL за четене във версия 8.0, е възможността за създаване на индекс в низходящ ред (или пренасочване на индекса). Предишните версии имаха само възходящо или обратно сканиране на индекса и MySQL трябваше да извърши сортиране на файлове, ако се нуждаеше от низходящ ред (ако е необходимо сортиране на файлове, може да помислите да проверите стойността на max_length_for_sort_data). Низходящите индекси също дават възможност на оптимизатора да използва индекси с множество колони, когато най-ефективният ред на сканиране смесва възходящ ред за някои колони и низходящ за други. Вижте тук за повече подробности.

Ресурси на процесора

По време на този сравнителен анализ реших да взема някои хардуерни ресурси, най-вече използването на процесора.

Нека първо обясня как използвам ресурса на процесора тук по време на сравнителния анализ. sysbench не включва колективна статистика за хардуерни ресурси, използвани или използвани по време на процеса, когато правите сравнителен анализ на база данни. Поради това това, което направих, е да създам флаг чрез създаване на файл, да се свържа с целевия хост чрез SSH и след това да събера данни от командата на Linux „top“ и да ги анализирам, докато спя за секунда, преди да събера отново. След това вземете най-забележителното увеличение на използването на процесора за процеса mysqld и след това премахнете флаг файла. Можете да прегледате кода, който имам в github.

Така че нека обсъдим отново резултата от графиката, изглежда разкрива, че MySQL 8.0 консумира много CPU. Повече от MySQL 5.7. Въпреки това, може да се наложи да се справи с нови променливи, добавени в MySQL 8.0. Например, тези променливи могат да повлияят на вашия MySQL 8.0 сървър:

  • innodb_log_spin_cpu_abs_lwm =80
  • innodb_log_spin_cpu_pct_hwm =50
  • innodb_log_wait_for_flush_spin_hwm =400
  • innodb_parallel_read_threads =4

Променливите с нейните стойности са оставени от стойностите по подразбиране за този показател. Първите три променливи обработват CPU за повторно регистриране, което в MySQL 8.0 е подобрение поради препроектирането на начина, по който InnoDB записва в REDO дневника. Променливата innodb_log_spin_cpu_pct_hwm има афинитет на процесора, което означава, че ще игнорира други ядра на процесора, ако mysqld е закрепен само към 4 ядра, например. За нишки за паралелно четене в MySQL 8.0 той добавя нова променлива, за която можете да настроите колко нишки да се използват.

Все пак не задълбавах в темата. Възможно е да има начини, по които производителността може да бъде подобрена, като се възползвате от функциите, които MySQL 8.0 може да предложи.

Заключение

Има много подобрения, които присъстват в MySQL 8.0. Резултатите от сравнителния анализ разкриват, че има впечатляващо подобрение, не само по отношение на управлението на работните натоварвания за четене, но и при високо натоварване при четене/запис в сравнение с MySQL 5.7.

Преминавайки към новите функции на MySQL 8.0, изглежда, че се е възползвал от най-актуалните технологии не само за софтуера (като страхотно подобрение за Memcached, отдалечено управление за по-добра работа на DevOps и т.н.), но също и в хардуера. Взет например замяната на latin1 с UTF8MB4 като кодиране на символи по подразбиране. Това би означавало, че ще изисква повече дисково пространство, тъй като UTF8 се нуждае от 2 байта за символите, които не са US-ASCII. Въпреки че този бенчмарк не се възползва от използването на новия метод за удостоверяване с caching_sha2_password, той няма да повлияе на производителността дали използва криптиране. След като бъде удостоверен, той се съхранява в кеша, което означава, че удостоверяването се извършва само веднъж. Така че, ако използвате един потребител за своя клиент, това няма да е проблем и е по-сигурно от предишните версии.

Тъй като MySQL използва най-актуалния хардуер и софтуер, той променя своите променливи по подразбиране. Можете да прочетете тук за повече подробности.

Като цяло MySQL 8.0 доминира ефективно над MySQL 5.7.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Да съкратите всички таблици в MySQL база данни с една команда?

  2. Използвайте композитен първичен ключ като външен ключ

  3. Как да наблюдавате MySQL/MariaDB бази данни с помощта на Netdata на CentOS 7

  4. Приставката за удостоверяване „caching_sha2_password“ не се поддържа

  5. MySQL - мога ли да огранича максималното време, позволено за изпълнение на заявка?