sql >> Databasteknik >  >> RDS >> Mysql

Vad är nytt med MySQL-replikering i MySQL 8.0

Replikering i MySQL har funnits länge och har stadigt förbättrats under åren. Det har varit mer som evolution snarare än revolution. Detta är fullt förståeligt, eftersom replikering är en viktig egenskap som många är beroende av - den måste fungera.

I de senaste MySQL-versionerna har vi sett förbättringar i replikeringsprestanda genom stöd för att tillämpa transaktioner parallellt. I MySQL 5.6 gjordes parallellisering på schemanivå - alla transaktioner som har utförts i separata scheman kunde exekveras på en gång. Detta var en trevlig förbättring för de arbetsbelastningar som hade flera scheman på en enda server, och belastningen fördelades mer eller mindre jämnt över schemana.

I MySQL 5.7 lades en annan parallelliseringsmetod till, så kallad "logisk klocka". Det gjorde det möjligt att få en viss grad av samtidighet på en slav, även om all din data har lagrats i ett enda schema. Det baserades kort sagt på det faktum att vissa transaktioner skulle förbinda sig på grund av en latens som lagts till av hårdvara. Du kan till och med lägga till den latensen manuellt för att uppnå bättre parallellisering på slavarna med binlog_group_commit_sync_delay.

Denna lösning var riktigt trevlig men inte utan nackdelar. Varje försening i att genomföra en transaktion kan så småningom påverka delar av applikationen som är vända mot användaren. Visst, du kan ställa in fördröjningar inom ett intervall på flera millisekunder, men även då är det ytterligare latens som saktar ner appen.

Förbättringar av replikeringsprestanda i MySQL 8.0

MySQL 8.0, som från och med nu (augusti 2017) fortfarande är i betaläge, ger några fina förbättringar av replikering. Ursprungligen utvecklades den för gruppreplikering (GR), men eftersom GR använder vanlig replikering under huven, gynnades "normal" MySQL-replikering av det. Förbättringen vi nämnde är beroendespårningsinformation som lagras i den binära loggen. Det som händer är att MySQL 8.0 nu har ett sätt att lagra information om vilka rader som påverkades av en given transaktion (så kallad skrivuppsättning), och den jämför skrivuppsättningar från olika transaktioner. Detta gör det möjligt att identifiera de transaktioner som inte fungerade på samma delmängd av rader och därför kan dessa tillämpas parallellt. Detta kan göra det möjligt att öka parallelliseringsnivån med flera gånger jämfört med implementeringen från MySQL 5.7. Vad du behöver tänka på är att en slav så småningom kommer att se en annan vy av data, en som aldrig dök upp på mastern. Detta beror på att transaktioner kan tillämpas i en annan ordning än på mastern. Detta borde dock inte vara ett problem. Den nuvarande implementeringen av flertrådsreplikering i MySQL 5.7 kan också orsaka detta problem om du inte uttryckligen aktiverar slave-preserve-commit-order.

För att kontrollera detta nya beteende, en variabel binlog_transaction_dependency_tracking har införts. Det kan ta tre värden:

  • COMMIT_ORDER:detta är standarden, den använder standardmekanismen som är tillgänglig i MySQL 5.7.
  • WRITESET:Det möjliggör bättre parallellisering och mastern börjar lagra skrivuppsättningsdata i binär logg.
  • WRITESET_SESSION:Detta säkerställer att transaktioner kommer att exekveras på slaven i ordning och problemet med en slav som ser ett databastillstånd som aldrig sågs på mastern elimineras. Det minskar parallelliseringen men det kan fortfarande ge bättre genomströmning än standardinställningarna.

Benchmark

I juli, på mysqlhighavailability.com, skrev Vitor Oliveira ett inlägg där han försökte mäta prestandan för nya lägen. Han använde det bästa scenariot - ingen som helst hållbarhet, för att visa upp skillnaden mellan gamla och nya lägen. Vi bestämde oss för att använda samma tillvägagångssätt, den här gången i en mer verklig uppsättning:binär logg aktiverad med log_slave_updates. Hållbarhetsinställningarna lämnades till standard (så, sync_binlog=1 - det är ny standard i MySQL 8.0, dubbelskrivningsbuffert aktiverad, InnoDB-kontrollsummor aktiverade etc.) Enda undantaget i hållbarhet var innodb_flush_log_at_trx_commit satt till 2.

Vi använde m4.2xl-instanser, 32G, 8 kärnor (så slave_parallel_workers sattes till 8). Vi använde också sysbench, oltp_read_write.lua script. 16 miljoner rader i 32 tabeller lagrades på 1000 GB gp2-volym (det är 3000 IOPS). Vi testade prestandan för alla lägen för 1, 2, 4, 8, 16 och 32 samtidiga sysbench-anslutningar. Processen var som följer:stoppa slav, exekvera 100 000 transaktioner, starta slav och beräkna hur lång tid det tar att rensa slavfördröjningen.

Först och främst vet vi inte riktigt vad som hände när sysbench kördes med endast en tråd. Varje test utfördes fem gånger efter en uppvärmningskörning. Denna speciella konfiguration testades två gånger - resultaten är stabila:enkeltrådad arbetsbelastning var den snabbaste. Vi kommer att undersöka det ytterligare för att förstå vad som hände.

Utöver det är resten av resultaten i linje med vad vi förväntade oss. COMMIT_ORDER är den långsammaste, speciellt för låg trafik, 2-8 trådar. WRITESET_SESSION presterar vanligtvis bättre än COMMIT_ORDER men det är långsammare än WRITESET för låg samtidig trafik.

Hur kan det hjälpa mig?

Den första fördelen är uppenbar:om din arbetsbelastning är på den långsamma sidan men dina slavar har en tendens att falla tillbaka i replikering, kan de dra nytta av förbättrad replikeringsprestanda så snart mastern kommer att uppgraderas till 8.0. Två anteckningar här:först - den här funktionen är bakåtkompatibel och 5.7-slavar kan också dra nytta av den. För det andra - en påminnelse om att 8.0 fortfarande är i betaläge, vi rekommenderar inte att du använder betaprogramvara i produktionen, även om detta är ett stort behov att testa. Den här funktionen kan hjälpa dig inte bara när dina slavar släpar efter. De kan vara helt ikapp men när du skapar en ny slav eller omproviserar befintlig, kommer den slaven att släpa efter. Att ha möjligheten att använda "WRITESET"-läget kommer att göra processen att tillhandahålla en ny värd mycket snabbare.

Sammantaget kommer den här funktionen att ha mycket större inverkan än du kanske tror. Med tanke på alla riktmärken som visar regressioner i prestanda när MySQL hanterar trafik med låg samtidighet, är allt som kan hjälpa till att påskynda replikeringen i sådana miljöer en enorm förbättring.

Om du använder mellanliggande masters är detta också en funktion att leta efter. Vilken mellanliggande master som helst lägger till viss serialisering i hur transaktioner hanteras och exekveras - i verkligheten kommer arbetsbelastningen på en mellanliggande master nästan alltid att vara mindre parallell än på mastern. Att använda skrivuppsättningar för att möjliggöra bättre parallellisering förbättrar inte bara parallelliseringen på den mellanliggande mastern utan det kan också förbättra parallelliseringen på alla dess slavar. Det är till och med möjligt (även om det skulle kräva seriösa tester för att verifiera att alla delar kommer att passa korrekt) att använda en 8.0-mellanmästare för att förbättra replikeringsprestanda för dina slavar (kom ihåg att MySQL 5.7-slaven kan förstå skrivuppsättningsdata och använda den även om den kan inte generera den på egen hand). Naturligtvis låter det ganska knepigt att replikera från 8.0 till 5.7 (och det är inte bara för att 8.0 fortfarande är beta). Under vissa omständigheter kan detta fungera och kan påskynda CPU-användningen på dina 5.7-slavar.

Andra ändringar i MySQL-replikering

Vi introducerar skrivuppsättningar, även om det är det mest intressanta, är det inte den enda förändringen som hände med MySQL-replikering i MySQL 8.0. Låt oss gå igenom några andra, också viktiga förändringar. Om du råkar använda en master som är äldre än MySQL 5.0, kommer 8.0 inte att stödja dess binära loggformat. Vi förväntar oss inte att se många sådana inställningar, men om du använder mycket gammal MySQL med replikering är det definitivt dags att uppgradera.

Standardvärdena har ändrats för att se till att replikeringen är så kraschsäker som möjligt:​​master_info_repository och relay_log_info_repository är inställda på TABELL. Expire_log_days har också ändrats - nu är standardvärdet 30. Förutom expire_log_days , en ny variabel har lagts till, binlog_expire_log_seconds , vilket möjliggör en mer finkornig binlogrotationspolicy. Några ytterligare tidsstämplar har lagts till i den binära loggen för att förbättra observerbarheten av replikeringsfördröjning, vilket introducerar mikrosekundsgranularitet.

Detta är för all del inte en fullständig lista över ändringar och funktioner relaterade till MySQL-replikering. Om du vill veta mer kan du kontrollera MySQL-ändringsloggarna. Se till att du har granskat dem alla - hittills har funktioner lagts till i alla 8.0-versioner.

Som du kan se förändras MySQL-replikeringen fortfarande och blir bättre. Som vi sa i början, det måste vara en långsam process, men det är verkligen fantastiskt att se vad som ligger framför oss. Det är också trevligt att se arbetet för gruppreplikering rinner ner och återanvänds i den "vanliga" MySQL-replikeringen.


  1. Hur man sorterar rader av HTML-tabeller som anropas från MySQL

  2. Oracle Database Security:Databasrevision

  3. Ansluter till en MySQL-databas i .NET

  4. SQL:sök efter en sträng i varje varchar-kolumn i en databas