{"id":19909,"date":"2026-06-11T15:15:29","date_gmt":"2026-06-11T13:15:29","guid":{"rendered":"https:\/\/webhosting.de\/database-row-locking-mysql-concurrency-optimieren-performance-locks\/"},"modified":"2026-06-11T15:15:29","modified_gmt":"2026-06-11T13:15:29","slug":"database-raekkelasning-mysql-samtidighed-optimere-ydeevne-lase","status":"publish","type":"post","link":"https:\/\/webhosting.de\/da\/database-row-locking-mysql-concurrency-optimieren-performance-locks\/","title":{"rendered":"Forst\u00e5else af databasel\u00e5sning og samtidighedsproblemer i MySQL"},"content":{"rendered":"<p><strong>Databaser\u00e6kke<\/strong> I MySQL styrer l\u00e5sning n\u00f8jagtigt, hvilken transaktion der m\u00e5 l\u00e6se eller skrive hvilke r\u00e6kker og hvorn\u00e5r, og beskytter dermed mod mistede opdateringer og \u00bbdirty reads\u00ab. Jeg viser trin for trin, hvordan l\u00e5sning, <strong>MVCC<\/strong> og hvordan isolationsniveauerne spiller sammen, hvor der opst\u00e5r problemer med samtidighed, og hvordan jeg udformer foresp\u00f8rgsler, indekser og transaktioner, s\u00e5 der ikke opst\u00e5r blokeringer.<\/p>\n\n<h2>Centrale punkter<\/h2>\n<p>For at du hurtigt kan f\u00e5 et overblik over, hvad jeg fokuserer p\u00e5 i dette indl\u00e6g, vil jeg sammenfatte de vigtigste retningslinjer og kort sammenligne dem. P\u00e5 den m\u00e5de f\u00e5r du en overskuelig struktur til de f\u00f8lgende, mere dybdeg\u00e5ende <strong>Forklaringer<\/strong>.<\/p>\n<ul>\n  <li><strong>Rorl\u00e5se<\/strong> Begr\u00e6ns konflikter til enkelte r\u00e6kker i stedet for hele tabeller.<\/li>\n  <li><strong>MVCC<\/strong> g\u00f8r det muligt at l\u00e6se hurtigt uden permanente delte l\u00e5se.<\/li>\n  <li><strong>Isolering<\/strong> fastl\u00e6gger, hvilke afvigelser der m\u00e5 forekomme.<\/li>\n  <li><strong>Gap\/N\u00e6ste-tast<\/strong> Blokerer indekshuller mod fantomer.<\/li>\n  <li><strong>Bedste praksis<\/strong> reducerer blokeringer og deadlocks m\u00e6rkbart.<\/li>\n<\/ul>\n<p>I det f\u00f8lgende oms\u00e6tter jeg disse punkter til konkrete tiltag, som jeg bruger til at g\u00f8re produktive MySQL-instanser mere sikre og hurtigere. Hver anbefaling har til form\u00e5l at reducere <strong>Blokering<\/strong>, konsistente data og klare diagnostiske forl\u00f8b.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/06\/mysql-serverraum-9081.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Hvorfor er det n\u00f8dvendigt at kontrollere samtidighed?<\/h2>\n<p>Samtidige adgangsforesp\u00f8rgsler kommer i konflikt med hinanden, s\u00e5 snart flere sessioner fors\u00f8ger at l\u00e6se eller skrive de samme linjer, og derfor l\u00e6gger jeg v\u00e6gt p\u00e5 klare <strong>Transaktionsgr\u00e6nser<\/strong> 8. Uden regler risikerer man tabte opdateringer, \"dirty reads\", \"non-repeatable reads\" og \"phantoms\", som i sidste ende kan f\u00f8re til forkerte beslutninger i applikationskoden. Jeg forhindrer dette ved at sikre l\u00e6sekonsistens og g\u00f8re skrivekonflikter synlige tidligt i stedet for at overskrive dem i stilhed. Jo flere parallelle brugere der er aktive, desto vigtigere bliver sm\u00e5 l\u00e5seobjekter og korte <strong>Ventetider<\/strong>. Hvis man ignorerer dette, risikerer man datafejl, lange ventetider og timeouts.<\/p>\n\n<h2>Grundl\u00e6ggende om r\u00e6kkel\u00e5sning i MySQL<\/h2>\n<p>Row Locking s\u00e6tter l\u00e5se p\u00e5 enkelte r\u00e6kker, s\u00e5 andre r\u00e6kker forbliver frie og mere <strong>Parallelisme<\/strong> opst\u00e5r. En eksklusiv l\u00e5s beskytter skriveoperationer indtil commit, mens l\u00e6seadgang, afh\u00e6ngigt af isolationsniveauet, bruger delte l\u00e5se eller MVCC-snapshots. Intent-l\u00e5se fungerer som signaler p\u00e5 et h\u00f8jere niveau, s\u00e5 motoren hurtigere kan kontrollere l\u00e5sekompatibiliteten. Jeg bem\u00e6rker altid, at selv sm\u00e5 opdateringer kan ber\u00f8re mange linjer, hvis WHERE-betingelser er upr\u00e6cise, og der ikke er nogen <strong>Indeks<\/strong> f\u00f8rer til. N\u00f8jagtighed i filteret undg\u00e5r brede udelukkelsesomr\u00e5der og sk\u00e5ner samtidigheden.<\/p>\n<p>Det er ogs\u00e5 vigtigt at tage h\u00f8jde for samspillet med indekserne, da InnoDB l\u00e5ser via indeksstier; manglende eller uhensigtsm\u00e6ssige n\u00f8gler \u00f8ger antallet af ber\u00f8rte r\u00e6kker betydeligt. Hvis en s\u00e6tning udf\u00f8rer en fuld scanning, vokser l\u00e5sefeltet, hvilket \u00f8ger ventetiderne og fremmer deadlocks. Derfor planl\u00e6gger jeg fra starten de passende n\u00f8gler til hyppige stier og holder WHERE-klausulerne s\u00e5 specifikke som muligt. P\u00e5 den m\u00e5de forbliver mine l\u00e5se smalle, og andre transaktioner kommer hurtigere til <strong>Adgang<\/strong>. Det er den nemmeste m\u00e5de at sikre en j\u00e6vn l\u00e5sefunktion p\u00e5.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/06\/mysql_datenbank_probleme_4837.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Pessimistisk vs. optimistisk l\u00e5sning<\/h2>\n<p>Pessimistisk l\u00e5sning tager udgangspunkt i konflikter og sp\u00e6rrer tidligt, hvilket styrker integriteten, men tager tid, mens <strong>optimistisk<\/strong> Systemer, der opererer i realtid, kontrollerer f\u00f8rst ved afslutningen, om dataene har \u00e6ndret sig. I praksisorienterede MySQL-ops\u00e6tninger kombinerer jeg begge dele: For kritiske konti laver jeg transaktioner med FOR UPDATE, mens jeg bruger versioner til enheder, der sj\u00e6ldent kommer i konflikt. En versionskolonne eller et tidsstempel giver mig mulighed for at fastsl\u00e5 ved opdateringen, om nogen var hurtigere, uden at blokere linjen permanent. Opst\u00e5r der en konflikt, gentager jeg transaktionen m\u00e5lrettet eller udf\u00f8rer en tilpasset forretningslogik. P\u00e5 den m\u00e5de fordeler jeg belastningen mere j\u00e6vnt, reducerer ventetiderne og holder <strong>Korrekthed<\/strong> h\u00f8j.<\/p>\n<p>Jeg v\u00e6lger strategien ud fra den enkelte use case: Mange samtidige l\u00e6seadgange drager fordel af optimistiske tilgange, mens meget kritiske penge- eller lagerposteringer fungerer bedst med korte, men klare eksklusive l\u00e5se. M\u00e5let er altid at blokere kun s\u00e5 meget som n\u00f8dvendigt og opdage konflikter tidligt. Med denne tilgang undg\u00e5r jeg lange k\u00e6der af ventende sessioner. Dette \u00f8ger gennemstr\u00f8mningen og <strong>P\u00e5lidelighed<\/strong> i hverdagen.<\/p>\n\n<h2>Forst\u00e5else af isolationsniveauer og MVCC<\/h2>\n<p>Isoleringsniveauet bestemmer, hvor mange uregelm\u00e6ssigheder jeg tillader, og hvor strengt MySQL l\u00e5ser, hvorfor jeg bevidst v\u00e6lger niveauet ud fra den konkrete anvendelsessituation. READ COMMITTED forhindrer beskidte l\u00e6seadgange, REPEATABLE READ holder v\u00e6rdierne i en transaktion konsistente, og SERIALIZABLE sikrer den strengeste r\u00e6kkef\u00f8lge. InnoDB bruger <strong>MVCC<\/strong>, s\u00e5 l\u00e6sere n\u00e6sten altid kan undv\u00e6re delte l\u00e5se og alligevel se konsistente \u00f8jebliksbilleder. Hvis man arbejder med dette, b\u00f8r man forst\u00e5, hvorn\u00e5r gap- og next-key-l\u00e5se tr\u00e6der i kraft for at forhindre fantomer. For en mere dybdeg\u00e5ende forklaring kan det v\u00e6re en god id\u00e9 at kigge p\u00e5 <a href=\"https:\/\/webhosting.de\/da\/mysql-isolation-level-hosting-server-consistency-transaktioner\/\">Detaljer om isolationsniveauer<\/a>, s\u00e5 du kan vurdere effekterne korrekt for hvert trin.<\/p>\n<p>I nedenst\u00e5ende tabel er de g\u00e6ngse sikkerhedsniveauer opstillet i forhold til typiske sikkerhedsbrud og deres indvirkning p\u00e5 sp\u00e6rringer, s\u00e5 jeg kan tr\u00e6ffe det rigtige valg og undg\u00e5 un\u00f8dvendige <strong>Blokering<\/strong> undg\u00e5.<\/p>\n<table>\n  <thead>\n    <tr>\n      <th>Isolationsniveau<\/th>\n      <th>Tilladte afvigelser<\/th>\n      <th>L\u00e5seadf\u00e6rd (forenklet)<\/th>\n      <th>Typisk brug<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>L\u00c6SE UDEN FORPLIGTELSE<\/td>\n      <td>Dirty Reads, Non-Repeatable, Phantoms<\/td>\n      <td>N\u00e6sten ingen sp\u00e6rringer, h\u00f8j <strong>Risici<\/strong><\/td>\n      <td>Sj\u00e6ldent fornuftigt<\/td>\n    <\/tr>\n    <tr>\n      <td>L\u00c6S BEKR\u00c6FTET<\/td>\n      <td>Ikke-gentagelige, fantomer<\/td>\n      <td>L\u00e6sere bruger MVCC, skrivere <strong>X-Locks<\/strong><\/td>\n      <td>Rapporter, API'er med mange l\u00e6sninger<\/td>\n    <\/tr>\n    <tr>\n      <td>GENTAGELIG L\u00c6SNING<\/td>\n      <td>Phantoms nedsat af Next-Key<\/td>\n      <td>St\u00e6rk l\u00e6sekonsistens, m\u00e5lrettet <strong>Gap<\/strong>-L\u00e5se<\/td>\n      <td>Standard i InnoDB<\/td>\n    <\/tr>\n    <tr>\n      <td>SERIALISABLE<\/td>\n      <td>Ingen afvigelser<\/td>\n      <td>Bredere sp\u00e6rringer, mindre <strong>Parallelisme<\/strong><\/td>\n      <td>H\u00f8jkritiske processer<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n<p>Jeg starter som regel med REPEATABLE READ og justerer m\u00e5lrettet, hvis foresp\u00f8rgsler blokerer for meget p\u00e5 grund af Next-Key-l\u00e5se. Omvendt bruger jeg kun SERIALIZABLE, hvor det er fagligt uundg\u00e5eligt, da ventetiderne ellers hober sig op. Med et klart valg for hver arbejdsbelastning holder jeg dataene konsistente og beskytter samtidig <strong>Ydelse<\/strong>. Denne tilgang sparer supporttid, da der sj\u00e6ldnere opst\u00e5r uventede spidsbelastninger. Dermed forbliver systemet forudsigeligt, selv n\u00e5r brugerantallet stiger.<\/p>\n\n<h2>MySQL-samtidighed i praksis<\/h2>\n<p>God parallelitet starter med velformulerede foresp\u00f8rgsler, der kun rammer de r\u00e6kker, der virkelig er brug for, s\u00e5 InnoDB kan <strong>R\u00e6kke<\/strong>-l\u00e5se. Jeg s\u00f8rger for, at filterbetingelserne er sargable, dvs. at de k\u00f8rer via indekser og ikke tvinger funktionskald p\u00e5 kolonner. Jeg holder opdateringerne fokuserede: en klar WHERE-klausul, et passende indeks og ingen un\u00f8dvendige sammenk\u00e6dninger i samme s\u00e6tning. I tilf\u00e6lde af reservationer bruger jeg FOR UPDATE sparsomt og kun for de faktisk ber\u00f8rte dataposter. Desuden undg\u00e5r jeg lange brugerinteraktioner mellem BEGIN og COMMIT, for hvert sekund \u00f8ger <strong>ventetid<\/strong> andre sessioner.<\/p>\n<p>N\u00e5r jeg inds\u00e6tter data i t\u00e6tpakkede indeksomr\u00e5der, tager jeg h\u00f8jde for, at Next-Key-l\u00e5se kan tr\u00e6de i kraft, hvilket kan medf\u00f8re, at flere transaktioner m\u00e5 vente. Jeg spreder hotspots ved at sprede n\u00f8gleomr\u00e5derne eller aflaste skrivestien til en lille, selvst\u00e6ndig k\u00f8. P\u00e5 den m\u00e5de reducerer jeg kollisionerne p\u00e5 den mest belastede tabel. Denne finjustering har st\u00f8rre effekt end at \u00f8ge timeouts, fordi f\u00e6rre <strong>Konflikter<\/strong> overhovedet opst\u00e5r. Netop derfor er det en god id\u00e9 at m\u00e5le dataadgangen inden systemet tages i brug.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/06\/mysql-row-locking-concurrency-9835.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Typiske problemer med samtidighed: blokering, d\u00f8dl\u00e5se, omfanget af l\u00e5se<\/h2>\n<p>Der opst\u00e5r blokering, n\u00e5r en transaktion venter p\u00e5 en linje, der allerede er blokeret, og derfor holder jeg transaktionerne korte og den p\u00e5g\u00e6ldende <strong>M\u00e6ngde<\/strong> begr\u00e6nser. Deadlocks opst\u00e5r, n\u00e5r to transaktioner blokerer hinanden, hvilket MySQL registrerer og afbryder den ene af dem. Jeg reagerer p\u00e5 dette med m\u00e5lrettede gentagelser og en konsistent adgangsr\u00e6kkef\u00f8lge p\u00e5 tv\u00e6rs af alle kodestier. L\u00e5seeskalering er sj\u00e6ldnere i InnoDB, men interne gr\u00e6nser begr\u00e6nser alligevel administrationsbyrden; store scanninger bringer motoren t\u00e6ttere p\u00e5 s\u00e5danne gr\u00e6nser. Hvis man ser tilbagevendende deadlocks, b\u00f8r man <a href=\"https:\/\/webhosting.de\/da\/database-deadlock-detection-handtering-hosting-infrastruktur\/\">Detektering og h\u00e5ndtering af deadlock<\/a> systematisk unders\u00f8ge og fjerne \u00e5rsagerne til konflikterne i stedet for blot at forl\u00e6nge timeout-perioderne.<\/p>\n<p>Efter min erfaring er der tre m\u00f8nstre, der is\u00e6r for\u00e5rsager lange ventetider: uindekserede filtre p\u00e5 hot-tabeller, FOR UPDATE uden en pr\u00e6cis WHERE-klausul og lang forretningslogik mellem l\u00e6se- og skrivetrin. Jeg fjerner dem ved at m\u00e5le hver sti enkeltvis, reducere l\u00e5setiden og tilpasse SQL-s\u00e6tningerne til indeksstier. Sm\u00e5 \u00e6ndringer i filteret eller r\u00e6kkef\u00f8lgen af opdateringerne l\u00f8ser ofte hele knudepunkter. S\u00e5danne korrektioner er billigere end flere <strong>Hardware<\/strong>, fordi de har en varig effekt. F\u00f8rst derefter er det v\u00e6rd at overveje vertikal eller horisontal skalering.<\/p>\n\n<h2>Gode r\u00e5d til at undg\u00e5 blokeringer og deadlocks<\/h2>\n<p>Jeg afslutter transaktioner hurtigt og lader ikke indtastningsfelter st\u00e5 \u00e5bne, mens der er l\u00e5se, fordi hvert sekund er spildt <strong>Ventelister<\/strong> Jeg s\u00f8rger altid for at behandle tabeller og r\u00e6kker i samme r\u00e6kkef\u00f8lge for at undg\u00e5 cykliske afh\u00e6ngigheder. Til rene l\u00e6seoperationer er READ COMMITTED ofte tilstr\u00e6kkeligt, mens jeg ved kritiske opdateringer bruger REPEATABLE READ eller kortvarigt FOR UPDATE. Indeksdesign er stadig et must: Uden en passende n\u00f8gle l\u00e5ser en s\u00e6tning hurtigt alt for mange r\u00e6kker. Fejlh\u00e5ndtering h\u00f8rer ogs\u00e5 med: Jeg opfanger deadlock-fejl, logger alle detaljer og fors\u00f8ger en kort, ren <strong>Pr\u00f8v igen<\/strong>.<\/p>\n<p>Overv\u00e5gning fuldender pakken: Jeg holder \u00f8je med ventetider, antallet af deadlocks og foresp\u00f8rgselsplaner og optimerer f\u00f8rst de mest markante spidsbelastninger. Sm\u00e5 forbedringer i hotpaths giver enorme gevinster, fordi de p\u00e5virker hver eneste foresp\u00f8rgsel. P\u00e5 den m\u00e5de opn\u00e5r jeg f\u00e6rre blokeringer, h\u00f8jere gennemstr\u00f8mning og p\u00e5lidelige svartider. Denne tilgang er langt mere overbevisende i den daglige drift end store oml\u00e6gninger. Rene rutiner sl\u00e5r generelle <strong>Handlinger<\/strong> n\u00e6sten altid.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/06\/techoffice2976.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>MySQL-specifikke tips til \u00f8get samtidighed<\/h2>\n<p>Jeg bruger bevidst autocommit: Enkelte s\u00e6tninger drager fordel af det, mens sammenh\u00e6ngende \u00e6ndringer i en kort, klar <strong>Transaktion<\/strong> lande. Jeg bruger SELECT \u2026 FOR UPDATE sparsomt og kun til de dataposter, jeg virkelig er n\u00f8dt til at reservere. Lange rapporter flytter jeg over p\u00e5 replikaer eller analytiske systemer, s\u00e5 OLTP-arbejdsbelastninger ikke bliver forsinket. Desuden tjekker jeg regelm\u00e6ssigt, hvilke s\u00e6tninger der holder us\u00e6dvanligt mange l\u00e5se, og hvorfor. Hvis du vil dykke dybere ned i emnet, b\u00f8r du l\u00e6se <a href=\"https:\/\/webhosting.de\/da\/mysql-storage-engine-innodb-myisam-webhosting-serverflux\/\">Lagringsmotor InnoDB<\/a> og bevidst evaluere indekslayouter i forhold til det egne skema, inden den n\u00e6ste version s\u00e6ttes i drift.<\/p>\n<p>Jeg minimerer hotspots ved at v\u00e6lge prim\u00e6rn\u00f8glerne p\u00e5 en s\u00e5dan m\u00e5de, at skrivebelastningen ikke konstant koncentreres i slutningen af et monotont voksende indeks. Jeg opdeler ogs\u00e5 batch-operationer i sm\u00e5 bidder for ikke at skabe lange eksklusive l\u00e5se. Med dette v\u00e6rkt\u00f8j holder l\u00e5sene kortere, og kontentionen falder m\u00e5lbart. Dermed falder fejlraten, og applikationen reagerer mere smidigt. S\u00e5dan frig\u00f8r jeg ressourcer uden straks at skabe nye <strong>Server<\/strong> opbygge.<\/p>\n\n<h2>Overv\u00e5gning og analyse: Hvad jeg m\u00e5ler<\/h2>\n<p>Jeg starter med m\u00e5linger af ventetider ved l\u00e5sning, antal deadlocks, lange transaktioner og de mest tidskr\u00e6vende s\u00e6tninger, s\u00e5 jeg kan identificere de st\u00f8rste <strong>H\u00e5ndtag<\/strong> . Performance-skemaet, SHOW ENGINE INNODB STATUS og logfilerne for langsomme foresp\u00f8rgsler giver mig konkrete spor. Derefter ser jeg p\u00e5 planerne for de v\u00e6rste foresp\u00f8rgsler og tjekker, om der mangler indekser, eller om filtre ikke er sargable. S\u00e5 snart jeg har fjernet flaskehalse, observerer jeg effekten over flere belastningsfaser. Denne cyklus af m\u00e5ling, \u00e6ndring og verifikation lader <strong>kvalitet<\/strong> konkurrencen stiger m\u00e6rkbart.<\/p>\n<p>For at kunne drage p\u00e5lidelige konklusioner har jeg brug for realistiske testdata og \u00e6gte adgangsmodeller, ikke blot syntetiske enkeltst\u00e5ende tests. Belastningsprofiler med samtidige sessioner viser, hvordan l\u00e5se virkelig fungerer. S\u00e5danne tests afsl\u00f8rer skjulte hotspots, som ellers f\u00f8rst opdages sent i den daglige drift. Hvis man tester udgivelser p\u00e5 denne m\u00e5de, undg\u00e5r man overraskelser i live-driften. Det sparer omkostninger, tid og nerver p\u00e5 lang sigt <strong>Udsigt<\/strong>.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/06\/mysql_locking_problem_3021.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Hostingmilj\u00f8 og databaseydelse<\/h2>\n<p>God parallelitet kr\u00e6ver hurtig hardware, for enhver IO-forsinkelse forl\u00e6nger <strong>L\u00e5setid<\/strong>. Jeg l\u00e6gger v\u00e6gt p\u00e5 hurtige SSD'er, tilstr\u00e6kkelig RAM til bufferpuljer og korte afstande mellem applikationen og databasen. CPU-reserver hj\u00e6lper med at udf\u00f8re parallelle foresp\u00f8rgsler uden flaskehalse. Jeg reducerer konsekvent netv\u00e6rksforsinkelser, s\u00e5 roundtrips ikke \u00f8ger den effektive ventetid. Hvis man holder \u00f8je med disse rammeforhold, f\u00e5r man reaktionsdygtige <strong>Tjenester<\/strong> og f\u00e6rre afbrydelser.<\/p>\n<p>Ogs\u00e5 fornuftige skaleringsstrategier t\u00e6ller: L\u00e6se-replikater til rapporter, sharding til meget store datas\u00e6t og separate systemer til analyseopgaver. Jeg v\u00e6lger f\u00f8rst efter m\u00e5ling, hvilken l\u00f8sning der er mest fordelagtig, og undg\u00e5r forhastede beslutninger. Arkitektur og SQL-disciplin supplerer hinanden; uden velformulerede foresp\u00f8rgsler er hardware kun en kortvarig l\u00f8sning. Med en velafbalanceret kombination reducerer jeg l\u00e5sekonflikter markant. Resultatet er en p\u00e5lidelig brugeroplevelse uden m\u00e6rkbare <strong>Ventetider<\/strong>.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/06\/mysql-zeilensperrung-4839.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Lock-typer i InnoDB i detaljer<\/h2>\n<p>For at kunne tr\u00e6ffe velovervejede beslutninger om s\u00f8gestier kender jeg de vigtigste l\u00e5setyper ud og ind: Record-l\u00e5se l\u00e5ser enkelte indeksposter, Gap-l\u00e5se l\u00e5ser mellemrummet mellem to indeksposter, og Next-Key-l\u00e5se er en kombination af de to. Sidstn\u00e6vnte forhindrer fantomer ved r\u00e6kkevidde-scanninger. Insert-Intention-Locks signalerer intentioner om inds\u00e6ttelser og tillader parallelle inds\u00e6ttelser i forskellige mellemrum uden at forstyrre hinanden un\u00f8digt. Ved entydige s\u00f8gninger via et unikt indeks reducerer InnoDB l\u00e5sen til en Record-Lock, hvilket minimerer blokeringer. S\u00e5 snart et Range-pr\u00e6dikat kommer ind i billedet (BETWEEN, &gt;, LIKE med pr\u00e6fiks), tr\u00e6der der ofte en Next-Key-Lock i kraft og dermed et bredere l\u00e5seomr\u00e5de.<\/p>\n<p>Derfor planl\u00e6gger jeg foresp\u00f8rgslerne, s\u00e5 de s\u00e5 vidt muligt ender p\u00e5 entydige eller meget selektive indekser. Det er ikke kun WHERE, der afg\u00f8r det: Ogs\u00e5 ORDER BY, LIMIT og r\u00e6kkef\u00f8lgen af JOIN-s\u00e6t p\u00e5virker den valgte indeksvej \u2013 og dermed omfanget af l\u00e5sninger. En m\u00e5lrettet omskrivning, der bruger en ORDER BY med et passende indeks, kan undg\u00e5 Next-Key-l\u00e5se og reducere ventetiderne betydeligt.<\/p>\n\n<h2>M\u00e5lrettet brug af Locking-Reads<\/h2>\n<p>Locking-Reads er nyttige, n\u00e5r jeg skal reservere r\u00e6kker eller koordinere konkurrerende opdateringer. I MySQL bruger jeg:<\/p>\n<ul>\n  <li>SELECT \u2026 FOR UPDATE: eksklusiv l\u00e5sning af de l\u00e6ste r\u00e6kker, velegnet til reservering f\u00f8r en opdatering.<\/li>\n  <li>SELECT \u2026 FOR SHARE (eller LOCK IN SHARE MODE i \u00e6ldre versioner): f\u00e6lles l\u00e5sning for at sikre konsistente l\u00e6sninger med skrivebeskyttelse.<\/li>\n  <li>NOWAIT og SKIP LOCKED: undg\u00e5 lange ventetider \u2013 NOWAIT afbryder straks, SKIP LOCKED springer l\u00e5ste linjer over.<\/li>\n<\/ul>\n<p>Et almindeligt m\u00f8nster for jobk\u00f8er:<\/p>\n<pre><code>START TRANSACTION;\nSELECT id, payload\nFROM jobs\nWHERE status = 'ready'\nORDER BY priority, id\nLIMIT 50\nFOR UPDATE SKIP LOCKED;\n-- mark\u00e9r som 'processing' og commit\nUPDATE jobs SET status = 'processing' WHERE id IN (...);\nCOMMIT;<\/code><\/pre>\n<p>S\u00e5dan behandler jeg opgaver parallelt uden at de blokerer hinanden. Det vigtigste er: pr\u00e6cise WHERE-s\u00e6tninger, et passende indeks p\u00e5 (status, priority, id) og korte transaktioner.<\/p>\n\n<h2>Forst\u00e5else af metadata-l\u00e5se (MDL)<\/h2>\n<p>Ud over r\u00e6kkel\u00e5se findes der metadatal\u00e5se, der koordinerer DDL og DML. Hver k\u00f8rende foresp\u00f8rgsel opretholder en MDL-l\u00e6sel\u00e5s p\u00e5 de ber\u00f8rte tabeller; DDL kr\u00e6ver eksklusive MDL-l\u00e5se. En uovervejet ALTER TABLE kan derfor vente, indtil lange transaktioner eller rapporter er afsluttet \u2013 omvendt blokerer en DDL igen nye DML-adgange. Jeg planl\u00e6gger derfor skema\u00e6ndringer uden for spidsbelastningen, reducerer transaktionsvarighederne og kontrollerer f\u00f8r implementeringer, om sessioner holder tabeller \u00e5bne i flere minutter. Online-DDL-varianter afhj\u00e6lper mange problemer, men erstatter ikke disciplin med hensyn til transaktionstider. I overv\u00e5gningen holder jeg specifikt \u00f8je med MDL-ventetider, fordi de signalerer undg\u00e5elige flaskehalse.<\/p>\n\n<h2>Fremmedn\u00f8gler, kaskader og indekskrav<\/h2>\n<p>Fremmedn\u00f8gler forbedrer datakvaliteten, men \u00f8ger l\u00e5seaftrykket. InnoDB kontrollerer konsistensen via indekser \u2013 hvis disse mangler p\u00e5 fremmedn\u00f8gles\u00f8jlerne, risikerer man omfattende scanninger og lange l\u00e5sninger. Derfor s\u00f8rger jeg for indekser p\u00e5 hver refererende kolonne. Kaskaderende opdateringer\/sletninger kan l\u00e5se flere tabeller i en transaktion og dermed fremme deadlocks. Jeg definerer en fast adgangsr\u00e6kkef\u00f8lge for alle ber\u00f8rte tabeller og holder \u00e6ndringerne sm\u00e5. Hvor kaskader sj\u00e6ldent forekommer fagligt, unders\u00f8ger jeg alternativer: eksplicitte, korte trin med klare WHERE-betingelser for at holde l\u00e5setiden forudsigelig.<\/p>\n\n<h2>Automatisk inkrementering, hotspots og bulk-inds\u00e6ttelser<\/h2>\n<p>Prim\u00e6rn\u00f8gler, der vokser monotont, skaber et hotspot i slutningen af den grupperede indeks. Mange parallelle inds\u00e6ttelser m\u00f8des der, hvilket \u00f8ger ventetiden. Jeg spreder n\u00f8glerne (f.eks. ved hj\u00e6lp af partitionsn\u00f8gler eller foranstillet entitets-ID) eller bruger batchst\u00f8rrelser, der er korte og committer rent. Jeg styrer auto-increment-adf\u00e6rden via lock-mode: Til OLTP foretr\u00e6kker jeg indstillinger, der tillader parallelle inds\u00e6ttelser og kun sp\u00e6rrer kortvarigt. Ved store batches tjekker jeg, om en COPY-lignende sti eller sm\u00e5, gentagelige delm\u00e6ngder er hurtigere. Det er stadig vigtigt at oprette indekser f\u00f8rst efter store indl\u00e6sningsprocesser eller aflaste sekund\u00e6re indekser undervejs for at reducere inds\u00e6tningshotspots.<\/p>\n\n<h2>Replikering og konsistente l\u00e6sninger<\/h2>\n<p>N\u00e5r jeg l\u00e6ser fra replikaer, tager jeg h\u00f8jde for forsinkelser: Ellers kan en rapport vise for\u00e6ldede data. For at sikre konsistente snapshots starter jeg bevidst transaktioner med WITH CONSISTENT SNAPSHOT og s\u00e6tter READ ONLY, hvis der kun l\u00e6ses. P\u00e5 den m\u00e5de opretholder jeg et stabilt overblik over flere statements \u2013 uden un\u00f8dvendige l\u00e5sninger. Samtidig s\u00f8rger jeg for, at applikationen har tolerante stier ved replikeringsforsinkelser eller om n\u00f8dvendigt skifter til prim\u00e6rserveren, hvis absolut aktualitet er afg\u00f8rende. Det mindsker overraskelser og forklarer tilsyneladende \u201eanomalier\u201c, der i virkeligheden kun er replikeringsforsinkelser.<\/p>\n\n<h2>Konfiguration og strategier for gentagelse<\/h2>\n<p>Jeg tilpasser ventetider for l\u00e5se og detektering p\u00e5 en fornuftig m\u00e5de: En moderat indstilling af `innodb_lock_wait_timeout` forhindrer, at sessioner blokeres i flere minutter. Jeg opdager deadlocks proaktivt og skelner klart: Fejl 1213 (deadlock) henter jeg kort med backoff og jitter; fejl 1205 (lock wait timeout) betragter jeg som et signal om at optimere foresp\u00f8rgselsstien. innodb_deadlock_detect hj\u00e6lper ved mange korte transaktioner; ved ekstremt h\u00f8j parallelitet kan cost-benefit-analysen tippe \u2013 s\u00e5 er det n\u00e6sten altid bedre at aflaste hotspots end blot at justere parametrene.<\/p>\n<p>Gentagelser er kun sikre, hvis operationerne er idempotente. Jeg udformer opdateringsstier s\u00e5ledes, at et gentaget fors\u00f8g n\u00e5r frem til den samme m\u00e5ltilstand (f.eks. med versionskolonner, deterministiske s\u00e6t i stedet for inkrementer eller klare forretningsh\u00e6ndelser). P\u00e5 den m\u00e5de forhindrer jeg dobbeltbogf\u00f8ringer og sikrer, at koden er robust over for uundg\u00e5elige konflikter.<\/p>\n\n<h2>Eksempler: Batches uden brede sp\u00e6rringer<\/h2>\n<p>Store \u00e6ndringer opdeler jeg i sm\u00e5, indeksbaserede bidder ud fra prim\u00e6rn\u00f8glen:<\/p>\n<pre><code>-- Eksempel: Sletning i batches\nSET @last_id = 0;\nWHILE 1 DO\n  DELETE FROM events\n  WHERE id &gt; @last_id\n  ORDER BY id\n  LIMIT 1000;\n  SET @rows = ROW_COUNT();\n  IF @rows = 0 THEN LEAVE; END IF;\n  SET @last_id = (SELECT MAX(id) FROM events WHERE id &lt;= @last_id + 1000);\nEND WHILE;<\/code><\/pre>\n<p>Dette m\u00f8nster holder transaktionerne korte, reducerer l\u00e5setiderne og giver plads til andre arbejdsopgaver. Jeg g\u00f8r p\u00e5 samme m\u00e5de ved masseopdateringer: F\u00f8rst udv\u00e6lger jeg m\u00e5l-ID'erne i en midlertidig m\u00e6ngde (eller via et LIMIT-vindue), derefter skriver jeg m\u00e5lrettet og committer hurtigt.<\/p>\n\n<h2>Hurtig diagnosevejledning<\/h2>\n<p>N\u00e5r ventetiden bliver lang, arbejder jeg i en fast r\u00e6kkef\u00f8lge:<\/p>\n<ol>\n  <li>Indsn\u00e6vr symptomet: Hvilke tabeller, hvilke s\u00e6tninger, hvilket tidspunkt?<\/li>\n  <li>G\u00f8r ventek\u00f8er synlige: Find data_locks\/data_lock_waits og blokerende PID'er i Performance Schema; tjek desuden den aktuelle InnoDB-status.<\/li>\n  <li>Kontroller foresp\u00f8rgselsplanen: Bruger foresp\u00f8rgslen den forventede indeks? Kan pr\u00e6dikaterne lagres?<\/li>\n  <li>Reducer omfanget af l\u00e5sninger: Pr\u00e6ciser WHERE-s\u00e6tningen, tilf\u00f8j indekser, undg\u00e5 r\u00e6kkevidde-scanninger, indsn\u00e6vr l\u00e5se-l\u00e6sninger.<\/li>\n  <li>Reducer transaktionstiden: Fjern interaktioner og eksterne opkald fra transaktionen, og reducer resultats\u00e6ttene.<\/li>\n  <li>Gentag og m\u00e5l: Efter \u00e6ndringen skal du igen observere og sammenligne spidsbelastningstiderne.<\/li>\n<\/ol>\n<p>Denne fremgangsm\u00e5de forhindrer, at man flyver i blinde. I stedet for at \u00f8ge tidsgr\u00e6nserne fjerner jeg \u00e5rsagerne \u2013 det er mere b\u00e6redygtigt og som regel hurtigere.<\/p>\n\n<h2>Undg\u00e5 operationelle faldgruber<\/h2>\n<p>Der er tre ting, jeg er s\u00e6rlig opm\u00e6rksom p\u00e5 i drift: For det f\u00f8rste s\u00f8rger jeg for ikke ved en fejltagelse at deaktivere autocommit globalt \u2013 det forl\u00e6nger l\u00e5sninger, uden at man bem\u00e6rker det. For det andet s\u00f8rger jeg for, at forbindelsespuljer ikke videregiver transaktioner, der allerede har \u00e5bne l\u00e5se. For det tredje bruger jeg m\u00e5lrettet savepoints til delvise tilbagekaldelser, men forventer ikke, at de forkorter l\u00e5setiderne: L\u00e5sen forbliver aktiv indtil commit eller rollback. Tydelig disciplin i app-laget betaler sig her direkte i form af kortere ventetider.<\/p>\n\n<h2>Kort og pr\u00e6cist: De vigtigste erfaringer<\/h2>\n<p>Row Locking sikrer datakonsistens, men kun i kombination med <strong>MVCC<\/strong>, passende isolationsniveauer og et velstruktureret indeksdesign kommer dets styrke til sin ret. Jeg holder transaktionerne korte, filtrerer m\u00e5lrettet og bruger kun FOR UPDATE, hvor det er fagligt n\u00f8dvendigt at reservere data. Jeg reducerer konflikter gennem konsistente adgangsr\u00e6kkef\u00f8lger og klare gentagelser ved deadlocks. Jeg v\u00e6lger isolationsniveauer pr. use case og observerer, hvordan gap- og next-key-locks p\u00e5virker. Den, der m\u00e5ler og j\u00e6vnligt finjusterer, opn\u00e5r h\u00f8j <strong>Samtidighed<\/strong> uden overraskelser.<\/p>\n<p>I sidste ende er der tre ting, der t\u00e6ller: sm\u00e5 l\u00e5seobjekter, korte holdetider og gennemsigtige foresp\u00f8rgselsstier. Med disse principper k\u00f8rer MySQL-arbejdsbelastninger p\u00e5lideligt, selv n\u00e5r mange brugere er aktive p\u00e5 samme tid. Jeg satser p\u00e5 gentagelige tests, meningsfulde m\u00e5linger og m\u00e5lrettede optimeringer i stedet for store oml\u00e6gninger. S\u00e5 forbliver dataene korrekte, responstiderne lave og deadlocks sj\u00e6ldne. Det er pr\u00e6cis, hvad hvert team forventer af en responsiv <strong>Database<\/strong>.<\/p>","protected":false},"excerpt":{"rendered":"<p>L\u00e6r, hvordan Database Row Locking fungerer, og hvordan du optimerer MySQL-samtidighed. Undg\u00e5 transaktionsblokeringer og deadlocks med praktiske tips.<\/p>","protected":false},"author":1,"featured_media":19902,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[781],"tags":[],"class_list":["post-19909","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-datenbanken-administration-anleitungen"],"acf":[],"_wp_attached_file":null,"_wp_attachment_metadata":null,"litespeed-optimize-size":null,"litespeed-optimize-set":null,"_elementor_source_image_hash":null,"_wp_attachment_image_alt":null,"stockpack_author_name":null,"stockpack_author_url":null,"stockpack_provider":null,"stockpack_image_url":null,"stockpack_license":null,"stockpack_license_url":null,"stockpack_modification":null,"color":null,"original_id":null,"original_url":null,"original_link":null,"unsplash_location":null,"unsplash_sponsor":null,"unsplash_exif":null,"unsplash_attachment_metadata":null,"_elementor_is_screenshot":null,"surfer_file_name":null,"surfer_file_original_url":null,"envato_tk_source_kit":null,"envato_tk_source_index":null,"envato_tk_manifest":null,"envato_tk_folder_name":null,"envato_tk_builder":null,"envato_elements_download_event":null,"_menu_item_type":null,"_menu_item_menu_item_parent":null,"_menu_item_object_id":null,"_menu_item_object":null,"_menu_item_target":null,"_menu_item_classes":null,"_menu_item_xfn":null,"_menu_item_url":null,"_trp_menu_languages":null,"rank_math_primary_category":null,"rank_math_title":null,"inline_featured_image":null,"_yoast_wpseo_primary_category":null,"rank_math_schema_blogposting":null,"rank_math_schema_videoobject":null,"_oembed_049c719bc4a9f89deaead66a7da9fddc":null,"_oembed_time_049c719bc4a9f89deaead66a7da9fddc":null,"_yoast_wpseo_focuskw":null,"_yoast_wpseo_linkdex":null,"_oembed_27e3473bf8bec795fbeb3a9d38489348":null,"_oembed_c3b0f6959478faf92a1f343d8f96b19e":null,"_trp_translated_slug_en_us":null,"_wp_desired_post_slug":null,"_yoast_wpseo_title":null,"tldname":null,"tldpreis":null,"tldrubrik":null,"tldpolicylink":null,"tldsize":null,"tldregistrierungsdauer":null,"tldtransfer":null,"tldwhoisprivacy":null,"tldregistrarchange":null,"tldregistrantchange":null,"tldwhoisupdate":null,"tldnameserverupdate":null,"tlddeletesofort":null,"tlddeleteexpire":null,"tldumlaute":null,"tldrestore":null,"tldsubcategory":null,"tldbildname":null,"tldbildurl":null,"tldclean":null,"tldcategory":null,"tldpolicy":null,"tldbesonderheiten":null,"tld_bedeutung":null,"_oembed_d167040d816d8f94c072940c8009f5f8":null,"_oembed_b0a0fa59ef14f8870da2c63f2027d064":null,"_oembed_4792fa4dfb2a8f09ab950a73b7f313ba":null,"_oembed_33ceb1fe54a8ab775d9410abf699878d":null,"_oembed_fd7014d14d919b45ec004937c0db9335":null,"_oembed_21a029d076783ec3e8042698c351bd7e":null,"_oembed_be5ea8a0c7b18e658f08cc571a909452":null,"_oembed_a9ca7a298b19f9b48ec5914e010294d2":null,"_oembed_f8db6b27d08a2bb1f920e7647808899a":null,"_oembed_168ebde5096e77d8a89326519af9e022":null,"_oembed_cdb76f1b345b42743edfe25481b6f98f":null,"_oembed_87b0613611ae54e86e8864265404b0a1":null,"_oembed_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_oembed_time_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_tldname":null,"_tldclean":null,"_tldpreis":null,"_tldcategory":null,"_tldsubcategory":null,"_tldpolicy":null,"_tldpolicylink":null,"_tldsize":null,"_tldregistrierungsdauer":null,"_tldtransfer":null,"_tldwhoisprivacy":null,"_tldregistrarchange":null,"_tldregistrantchange":null,"_tldwhoisupdate":null,"_tldnameserverupdate":null,"_tlddeletesofort":null,"_tlddeleteexpire":null,"_tldumlaute":null,"_tldrestore":null,"_tldbildname":null,"_tldbildurl":null,"_tld_bedeutung":null,"_tldbesonderheiten":null,"_oembed_ad96e4112edb9f8ffa35731d4098bc6b":null,"_oembed_8357e2b8a2575c74ed5978f262a10126":null,"_oembed_3d5fea5103dd0d22ec5d6a33eff7f863":null,"_eael_widget_elements":null,"_oembed_0d8a206f09633e3d62b95a15a4dd0487":null,"_oembed_time_0d8a206f09633e3d62b95a15a4dd0487":null,"_aioseo_description":null,"_eb_attr":null,"_eb_data_table":null,"_oembed_819a879e7da16dd629cfd15a97334c8a":null,"_oembed_time_819a879e7da16dd629cfd15a97334c8a":null,"_acf_changed":null,"_wpcode_auto_insert":null,"_edit_last":null,"_edit_lock":null,"_oembed_e7b913c6c84084ed9702cb4feb012ddd":null,"_oembed_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_time_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_03514b67990db061d7c4672de26dc514":null,"_oembed_time_03514b67990db061d7c4672de26dc514":null,"rank_math_news_sitemap_robots":null,"rank_math_robots":null,"_eael_post_view_count":"363","_trp_automatically_translated_slug_ru_ru":null,"_trp_automatically_translated_slug_et":null,"_trp_automatically_translated_slug_lv":null,"_trp_automatically_translated_slug_fr_fr":null,"_trp_automatically_translated_slug_en_us":null,"_wp_old_slug":null,"_trp_automatically_translated_slug_da_dk":null,"_trp_automatically_translated_slug_pl_pl":null,"_trp_automatically_translated_slug_es_es":null,"_trp_automatically_translated_slug_hu_hu":null,"_trp_automatically_translated_slug_fi":null,"_trp_automatically_translated_slug_ja":null,"_trp_automatically_translated_slug_lt_lt":null,"_elementor_edit_mode":null,"_elementor_template_type":null,"_elementor_version":null,"_elementor_pro_version":null,"_wp_page_template":null,"_elementor_page_settings":null,"_elementor_data":null,"_elementor_css":null,"_elementor_conditions":null,"_happyaddons_elements_cache":null,"_oembed_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_time_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_time_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_59808117857ddf57e478a31d79f76e4d":null,"_oembed_time_59808117857ddf57e478a31d79f76e4d":null,"_oembed_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_time_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_81002f7ee3604f645db4ebcfd1912acf":null,"_oembed_time_81002f7ee3604f645db4ebcfd1912acf":null,"_elementor_screenshot":null,"_oembed_7ea3429961cf98fa85da9747683af827":null,"_oembed_time_7ea3429961cf98fa85da9747683af827":null,"_elementor_controls_usage":null,"_elementor_page_assets":null,"_elementor_screenshot_failed":null,"theplus_transient_widgets":null,"_eael_custom_js":null,"_wp_old_date":null,"_trp_automatically_translated_slug_it_it":null,"_trp_automatically_translated_slug_pt_pt":null,"_trp_automatically_translated_slug_zh_cn":null,"_trp_automatically_translated_slug_nl_nl":null,"_trp_automatically_translated_slug_pt_br":null,"_trp_automatically_translated_slug_sv_se":null,"rank_math_analytic_object_id":null,"rank_math_internal_links_processed":"1","_trp_automatically_translated_slug_ro_ro":null,"_trp_automatically_translated_slug_sk_sk":null,"_trp_automatically_translated_slug_bg_bg":null,"_trp_automatically_translated_slug_sl_si":null,"litespeed_vpi_list":null,"litespeed_vpi_list_mobile":null,"rank_math_seo_score":null,"rank_math_contentai_score":null,"ilj_limitincominglinks":null,"ilj_maxincominglinks":null,"ilj_limitoutgoinglinks":null,"ilj_maxoutgoinglinks":null,"ilj_limitlinksperparagraph":null,"ilj_linksperparagraph":null,"ilj_blacklistdefinition":null,"ilj_linkdefinition":null,"_eb_reusable_block_ids":null,"rank_math_focus_keyword":"Database Row","rank_math_og_content_image":null,"_yoast_wpseo_metadesc":null,"_yoast_wpseo_content_score":null,"_yoast_wpseo_focuskeywords":null,"_yoast_wpseo_keywordsynonyms":null,"_yoast_wpseo_estimated-reading-time-minutes":null,"rank_math_description":null,"surfer_last_post_update":null,"surfer_last_post_update_direction":null,"surfer_keywords":null,"surfer_location":null,"surfer_draft_id":null,"surfer_permalink_hash":null,"surfer_scrape_ready":null,"_thumbnail_id":"19902","footnotes":null,"_links":{"self":[{"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/posts\/19909","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/comments?post=19909"}],"version-history":[{"count":0,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/posts\/19909\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/media\/19902"}],"wp:attachment":[{"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/media?parent=19909"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/categories?post=19909"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/tags?post=19909"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}