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

Обработка на големи транзакции с поточно репликация и MariaDB 10.4

Справянето с големи транзакции винаги е било болезнена точка в Galera Cluster. Начинът, по който работи сертифицирането на набора за запис на Galera, причинява проблеми, когато транзакциите са дълги или когато един ред се променя често на множество възли. В резултат на това транзакциите трябва да бъдат връщани и изпробвани отново, което води до спад в производителността. За щастие този проблем беше разгледан в Galera 4, нова версия на Galera от Codership. Тази библиотека се използва в MariaDB 10.4, така че инсталирането на MariaDB 10.4 е най-лесният начин за тестване на нововъведените функции. В тази публикация в блога ще разгледаме как репликацията на поточно предаване може да се използва за смекчаване на проблеми, които са били стандартен проблем в предишните версии на Galera.

Ще използваме три възела на MariaDB Galera cluster версия 10.4.6, която идва с версия на Galera от 26.4.2.

MariaDB [(none)]> show global status like 'wsrep_provider%';
+-----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name               | Value                                                                                                                                          |
+-----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
| wsrep_provider_capabilities | :MULTI_MASTER:CERTIFICATION:PARALLEL_APPLYING:TRX_REPLAY:ISOLATION:PAUSE:CAUSAL_READS:INCREMENTAL_WRITESET:UNORDERED:PREORDERED:STREAMING:NBO: |
| wsrep_provider_name         | Galera                                                                                                                                         |
| wsrep_provider_vendor       | Codership Oy <[email protected]>                                                                                                              |
| wsrep_provider_version      | 26.4.2(r4498)                                                                                                                                  |
+-----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
4 rows in set (0.001 sec)

Има три основни болезнени точки, с които стрийминг репликацията е предназначена да се справи:

  • Дълги транзакции
  • Големи транзакции
  • Горещи точки в таблици

Нека ги разгледаме един по един и да видим как репликацията на поточно предаване може да ни помогне да се справим с тях, но първо нека се съсредоточим върху сертифицирането на набора за запис – основната причина за появата на тези проблеми.

Сертификация Writeset в клъстер Galera

Клъстерът Galera се състои от множество възли с възможност за запис. Всяка транзакция, изпълнена в клъстер Galera, образува набор за запис. Всеки набор за запис трябва да бъде изпратен до всички възли в клъстера за сертифициране - процес, който гарантира, че всички възли могат да прилагат дадена транзакция. Наборите за запис трябва да се изпълняват на всички възли на клъстера, така че ако има някакъв конфликт, транзакцията не може да бъде ангажирана. Какви са типичните причини, поради които транзакцията не може да бъде ангажирана? Е, трите точки, които изброихме по-рано:

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

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

В Galera 4, с поточно репликация, поведението се промени и всички заключвания се вземат във всички възли. Транзакциите ще бъдат разделени на части и всяка част ще бъде сертифицирана на всички възли. След успешно сертифициране редовете ще бъдат заключени на всички възли в клъстера. Има няколко променливи, които управляват как точно се прави това - wsrep_trx_fragment_size и wsrep_trx_fragment_unit определят колко голям трябва да бъде фрагментът и как трябва да бъде дефиниран. Това е много фин контрол:можете да дефинирате фрагментна единица като байтове, изрази или редове, което прави възможно стартирането на сертифицирането за всеки ред, модифициран в транзакцията. Нека да разгледаме как можете да се възползвате от репликацията на поточно предаване в реалния живот.

Работа с поточно репликация

Нека разгледаме следния сценарий. Имаме транзакция за изпълнение, която отнема поне 30 секунди:

BEGIN; UPDATE sbtest.sbtest1 SET k = k - 2 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; SELECT SLEEP(30); COMMIT;

След това, докато работи, ще изпълним SQL, който докосва подобни редове. Това ще бъде изпълнено на друг възел:

BEGIN; UPDATE sbtest.sbtest1 SET k = k - 1 WHERE id < 20 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 20 ; COMMIT;

Какъв би бил резултатът?

Първата транзакция се отменя веднага щом се изпълни втората:

MariaDB [sbtest]> BEGIN; UPDATE sbtest.sbtest1 SET k = k - 2 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; SELECT SLEEP(30); COMMIT;
Query OK, 0 rows affected (0.001 sec)

Query OK, 667 rows affected (0.020 sec)
Rows matched: 667  Changed: 667  Warnings: 0

Query OK, 667 rows affected (0.010 sec)
Rows matched: 667  Changed: 667  Warnings: 0

Query OK, 667 rows affected (0.009 sec)
Rows matched: 667  Changed: 667  Warnings: 0

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
Query OK, 0 rows affected (0.001 sec)

Транзакцията на втория възел беше успешна:

MariaDB [(none)]> BEGIN; UPDATE sbtest.sbtest1 SET k = k - 1 WHERE id < 20 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 20 ; COMMIT;
Query OK, 0 rows affected (0.000 sec)

Query OK, 7 rows affected (0.002 sec)
Rows matched: 7  Changed: 7  Warnings: 0

Query OK, 7 rows affected (0.001 sec)
Rows matched: 7  Changed: 7  Warnings: 0

Query OK, 0 rows affected (0.004 sec)

Това, което можем да направим, за да го избегнем, е да използваме стрийминг репликация за първата транзакция. Ще помолим Galera да удостоверява всяка промяна на ред:

MariaDB [sbtest]> BEGIN; SET SESSION wsrep_trx_fragment_size=1 ; SET SESSION wsrep_trx_fragment_unit='rows' ; UPDATE sbtest.sbtest1 SET k = k - 2 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; SELECT SLEEP(30); COMMIT; SET SESSION wsrep_trx_fragment_size=0;
Query OK, 0 rows affected (0.001 sec)

Query OK, 0 rows affected (0.000 sec)

Query OK, 0 rows affected (0.000 sec)

Query OK, 667 rows affected (1.757 sec)
Rows matched: 667  Changed: 667  Warnings: 0

Query OK, 667 rows affected (1.708 sec)
Rows matched: 667  Changed: 667  Warnings: 0

Query OK, 667 rows affected (1.685 sec)
Rows matched: 667  Changed: 667  Warnings: 0

Както можете да видите, този път работи добре. На втория възел:

MariaDB [(none)]> BEGIN; UPDATE sbtest.sbtest1 SET k = k - 1 WHERE id < 20 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 20 ; COMMIT;
Query OK, 0 rows affected (0.000 sec)

Query OK, 7 rows affected (33.942 sec)
Rows matched: 7  Changed: 7  Warnings: 0

Query OK, 7 rows affected (0.001 sec)
Rows matched: 7  Changed: 7  Warnings: 0

Query OK, 0 rows affected (0.026 sec)

Интересното е, че можете да видите, че UPDATE отне почти 34 секунди, за да се изпълни - това се дължи на факта, че първоначалната транзакция, чрез поточно репликация, заключи всички модифицирани редове на всички възли и втората ни транзакция трябваше да изчака първият, който завърши, въпреки че и двете транзакции бяха изпълнени на различни възли.

Това е основно, когато става въпрос за репликация на поточно предаване. В зависимост от изискванията и трафика можете да го използвате по по-малко строг начин - ние сертифицирахме всеки ред, но можете да го промените на всеки n-ти ред или на всяко изявление. Можете дори да решите какъв обем данни да сертифицирате. Това трябва да е достатъчно, за да отговаря на изискванията на вашата среда.

Има още няколко неща, които бихме искали да имате предвид и да запомните. На първо място, поточно репликацията в никакъв случай не е решение, което трябва да се използва по подразбиране. Това е причината, поради която по подразбиране е деактивиран. Препоръчителният случай на използване е ръчно да вземете решение за транзакции, които биха се възползвали от поточно репликацията, и да го активирате на ниво сесия. Това е причината нашите примери да завършват с:

SET SESSION wsrep_trx_fragment_size=0;

Този израз (задаване на wsrep_trx_fragment_size на 0) деактивира репликацията на поточно предаване за текущата сесия.

Друго нещо, което си струва да запомните - ако случайно използвате стрийминг репликация, тя ще използва таблицата „wsrep_streaming_log“ в схемата „mysql“ за постоянно съхраняване на данните, които се предават поточно. С помощта на тази таблица можете да получите някаква представа за данните, които се прехвърлят в клъстера с помощта на поточно репликация.

И накрая, изпълнението. Това също е една от причините, поради които не искате да използвате поточно репликация през цялото време. Основната причина за това е заключване - с поточно репликация трябва да придобиете заключване на редове на всички възли. Това отнема време, за да получите заключванията и, ако трябва да връщате транзакцията, това също ще окаже натиск върху всички възли да извършат връщането. Проведохме много бърз тест за въздействието върху производителността, което репликацията на поточно предаване има. Средата е строго тестова, така че не приемайте, че тези резултати са еднакви за хардуера от производствен клас, по-скоро вие трябва да видите какво може да бъде въздействието.

Тествахме четири сценария:

  1. Основна линия, задайте глобално wsrep_trx_fragment_size=0;
  2. задаване глобално wsrep_trx_fragment_unit='редове'; задайте глобален wsrep_trx_fragment_size=1;
  3. задаване глобално wsrep_trx_fragment_unit='изявления'; задайте глобален wsrep_trx_fragment_size=1;
  4. задаване глобално wsrep_trx_fragment_unit='изявления'; задайте глобален wsrep_trx_fragment_size=5;

Използвахме sysbench r/w тест:

sysbench /root/sysbench/src/lua/oltp_read_write.lua --threads=4 --events=0 --time=300 --mysql-host=10.0.0.141 --mysql-user=sbtest --mysql-password=sbtest --mysql-port=3306 --tables=32 --report-interval=1 --skip-trx=off --table-size=100000 --db-ps-mode=disable run

Резултатите са:

  1. Транзакции:82,91 в сек., заявки:1658,27 в сек. (100%)
  2. Транзакции:54,72 в сек., заявки:1094,43 в сек. (66%)
  3. Транзакции:54,76 в сек., заявки:1095,18 в сек. (66%)
  4. Транзакции:70,93 в сек., заявки:1418,55 в сек. (86%)

Както можете да видите, въздействието е значително, производителността пада дори с 33%.

Надяваме се, че сте намерили тази публикация в блога информативна и ви даде известна представа за стрийминг репликацията, която идва с Galera 4 и MariaDB 10.4. Опитахме се да покрием случаите на употреба и потенциалните недостатъци, свързани с тази нова технология.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MariaDB CURRENT_TIME() Обяснено

  2. Как MOD() работи в MariaDB

  3. Как работи UNCOMPRESSED_LENGTH() в MariaDB

  4. Съвети за наблюдение на репликацията на MariaDB с ClusterControl

  5. Как INSTR() работи в MariaDB